- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
template <class T>
struct foo {
int x;
decltype(x) f1();
};
似乎不可能定义f1
out-of-line。我尝试了以下定义,但均无效:
template <class T> decltype(x) foo<T>::f1() {}
template <class T> auto foo<T>::f1() -> decltype(x) {}
template <class T> auto foo<T>::f1() { return x; }
template <class T> decltype(std::declval<foo<T>>().x) foo<T>::f1() {}
// This return type is copied from the gcc error message
template <class T> decltype (((foo<T>*)(void)0)->foo<T>::x) foo<T>::f1() {}
这在实际代码中不是问题,因为将 f1
的类内声明更改为 auto f1() -> decltype(x);
允许第二个定义。但我很困惑为什么这会改变任何事情。甚至可以声明原始的 f1
不在线吗?
最佳答案
尽管这看起来很愚蠢,但我相信以下内容是正确的:
template <class T>
struct foo {
int x;
decltype(x) f1();
};
template <class T>
int foo<T>::f1() { return 0; }
Clang 接受它,但 GCC 不接受,所以我要说我认为 GCC 有一个错误。 [ Coliru link ]
问题是 f1
的这两个声明是否声明相同的函数(更专业地说,是同一类模板的相同成员函数)。这由 [basic.link]/9 管理,据此:
Two names that are the same (Clause 6) and that are declared in different scopes shall denote the same variable, function, type, template or namespace if
- both names have external linkage or else both names have internal linkage and are declared in the same translation unit; and
- both names refer to members of the same namespace or to members, not by inheritance, of the same class; and
- when both names denote functions, the parameter-type-lists of the functions (11.3.5) are identical; and
- when both names denote function templates, the signatures (17.5.6.1) are the same.
如果返回类型实际上是相同的(因为根据 [defns.signature.member.templ],返回类型是类成员函数模板的签名的一部分),要求似乎得到满足。自 foo<T>::x
是int
, 它们是一样的。
如果 x
的类型不是这种情况被依赖。例如,GCC 和 Clang 在声明 x
时都拒绝定义。更改为 typename identity<T>::type x;
. [ Coliru link ] 在这种情况下,[temp.type]/2 将适用:
If an expression e is type-dependent (17.6.2.2),
decltype(
e)
denotes a unique dependent type. Two such decltype-specifiers refer to the same type only if their expressions are equivalent (17.5.6.1). [ Note: However, such a type may be aliased, e.g., by a typedef-name. — end note ]
也许 GCC 在考虑 x
时出错了依赖于类型(不应该)。但是,此注释提出了一种解决方法:
template <class T>
struct foo {
int x;
decltype(x) f1();
using x_type = decltype(x);
};
template <class T>
typename foo<T>::x_type foo<T>::f1() { return 0; }
这适用于 GCC 和 Clang。 [ Coliru link ]
关于c++ - 如何定义具有非尾随 decltype 返回类型的外联类模板成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49372823/
我是一名优秀的程序员,十分优秀!