考虑以下课程:
class MyClass
{
int _id;
public:
decltype(_id) getId();
};
decltype(MyClass::_id) MyClass::getId()
{
return _id;
}
它汇编得很好。
然而,当我从中制作模板类时:
template <class T>
class MyClass
{
int _id;
public:
decltype(_id) getId();
};
template <class T>
decltype(MyClass<T>::_id) MyClass<T>::getId()
{
return _id;
}
我明白了:
test.cpp:10:27: error: prototype for 'decltype (MyClass<T>::_id) MyClass<T>::getId()' does not match any in class 'MyClass<T>'
decltype(MyClass<T>::_id) MyClass<T>::getId()
^
test.cpp:6:19: error: candidate is: decltype (((MyClass<T>*)(void)0)->MyClass<T>::_id) MyClass<T>::getId()
decltype(_id) getId();
^
为什么?
为什么选择不同类型
decltype (MyClass<T>::_id) MyClass<T>::getId()
decltype (((MyClass<T>*)(void)0)->MyClass<T>::_id)
我可以通过在类中定义主体来修复它:
template <class T>
class MyClass
{
int _id;
public:
decltype(_id) getId() { return _id; }
};
尾随返回类型遇到类似的问题:
template <class T>
class MyClass
{
int _id;
public:
auto getId() -> decltype(_id);
};
template <class T>
auto MyClass<T>::getId() -> decltype(MyClass<T>::_id)
{
return _id;
}
错误:
test.cpp:10:6: error: prototype for 'decltype (MyClass<T>::_id) MyClass<T>::getId()' does not match any in class 'MyClass<T>'
auto MyClass<T>::getId() -> decltype(MyClass<T>::_id)
^
test.cpp:6:10: error: candidate is: decltype (((MyClass<T>*)this)->MyClass<T>::_id) MyClass<T>::getId()
auto getId() -> decltype(_id);
^
decltype (MyClass<T>::_id) MyClass<T>::getId()
decltype (((MyClass<T>*)this)->MyClass<T>::_id) MyClass<T>::getId()
g ++ 5.3.0
答案 0 :(得分:3)
根据标准草案N4582 §5.1.1/ p13一般[expr.prim.general] ( Emphasis Mine ):
表示非静态数据成员或非静态数据的id表达式 只能使用类的成员函数:
(13.1) - 作为类成员访问(5.2.5)对象的一部分 表达式是指成员的类 63 或类 派生自该类,或
(13.2) - 形成指向成员(5.3.1)或
的指针(13.3) - 如果该id-expression表示非静态数据成员及其 出现在未评估的操作数中。 [实施例:强>
struct S { int m; }; int i = sizeof(S::m); // OK int j = sizeof(S::m + 42); // OK
- 结束示例]
63)当对象表达式是隐式时,这也适用 (* this)(9.3.1)。
同样来自§7.1.6.2/ p4简单类型说明符[dcl.type.simple] ( Emphasis Mine ):
对于表达式
e
,decltype(e)
表示的类型定义为 如下:(4.1) - 如果
e
是未表示的id-expression或未表示的 类成员访问(5.2.5),decltype(e)
是实体的类型 以e命名。如果没有这样的实体,或者e命名一组 重载函数,程序格式不正确;(4.2) - 否则,如果e是xvalue,
的类型decltype(e)
是T&&
,其中T
是[{1}};(4.3) - 否则,如果e是左值,
的类型e
是decltype(e)
,其中T&
是T
;(4.4) - 否则,
e
是decltype(e)
的类型。
e
说明符的操作数是未评估的操作数(第5条)。[实施例:
decltype
- 结束示例] [注意:确定涉及的类型的规则 decltype(auto)在7.1.6.4中规定。 - 结束说明]
因此,由于const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 17; // type is const int&&
decltype(i) x2; // type is int
decltype(a->x) x3; // type is double
decltype((a->x)) x4 = x3; // type is const double&
是未评估的操作数,因此代码是合法的并且应该编译。
一个干净的解决方法是使用decltype
:
decltype(auto)
以上代码被GCC / CLANG / VC ++接受。
答案 1 :(得分:1)
似乎是GCC Bug 57712。
错误描述的示例代码:
generic_equiv code
0 0101010C0AAAAAA 0101010C0BBAAAA
1 0101010F0AAAUAU 0101010F0BCAAAU
2 NaN 0101010G0AAABAB