原型与decltype和auto不匹配
prototype mismatch with decltype and auto
考虑以下类:
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
根据标准草案N4582§5.1.1/13 General[expr.prim.General](Emphasis Mine):
表示非静态数据成员或非静态的id表达式只能使用类的成员函数:
(13.1)--作为类成员访问(5.2.5)的一部分,其中对象表达式是指成员的类63或类源自该类,或
(13.2)-形成指向成员(5.3.1)或的指针
(13.3)--如果id表达式表示非静态数据成员,并且出现在未求值的操作数中。[示例:
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表达式或未加括号类成员访问(5.2.5),decltype(e)
是实体的类型由e命名。如果没有这样的实体,或者如果e命名一组函数过载,程序格式错误;(4.2)——否则,如果e为x值,则
decltype(e)
为T&&
,其中CCD_ 11是CCD_;(4.3)——否则,如果e为左值,则
decltype(e)
为T&
,其中T
是CCD_ 16的类型;(4.4)——否则,
decltype(e)
为e
的类型。
decltype
说明符的操作数是未赋值的操作数(第5条)[示例:
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(auto)在7.1.6.4中有规定。——尾注]
因此,由于decltype
是未赋值的操作数,因此代码是合法的,应进行编译。
一个干净的解决方法是使用decltype(auto)
:
template<typename T>
class MyClass {
int _id;
public:
decltype(auto) getId();
};
template<typename T>
decltype(auto) MyClass<T>::getId() {
return _id;
}
以上代码已被GCC/CLANG/VC++接受。
这似乎是g++
错误。
我已经在Visual Studio 2015中试用了您的代码:
生成:1成功,0失败,0最新,0跳过
编辑:我找到了解决方法:
#include <iostream>
template <class T>
class MyClass
{
T _id = {0};
public:
decltype(((MyClass<T>*)nullptr)->_id) getId();
};
template <class T>
decltype(((MyClass<T>*)nullptr)->_id) MyClass<T>::getId()
{
return _id;
}
int main()
{
MyClass<int> f;
auto n = f.getId();
std::cout << n << 'n'; // output: 0
}
输出:
0
这似乎是GCC Bug 57712。
错误描述的示例代码:
struct Test {
int method(int value) { return value; }
template <typename T>
auto test(T value) -> decltype(this->method(value));
};
template <typename T>
auto Test::test(T value) -> decltype(this->method(value)) {
return this->method(value);
}
- Qt SQLite没有查询或参数计数不匹配
- 模板参数推导失败,函数参数/参数不匹配
- 在使用累加时,C++中的运算符+不匹配
- C++ 与操作员不匹配<<
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- 与'operator='不匹配(操作数类型'String'且"void")
- C++模板/别名 - 模板参数列表中参数 1 处的类型/值不匹配
- C4018:类内有符号、无符号不匹配
- 我在 .h 中有一个枚举类,并且在.cpp错误中有一个运算符重载:与"运算符<<不匹配
- 为什么我收到错误:"运算符<<不匹配?
- RE2 不匹配非 ASCII 字符
- 函数签名与调用的函数不匹配,常量字符[]和字符*之间的区别?
- 模板推导:为什么函数指针模板定义在常量和/或引用时不匹配?
- 错误:"模板<类_Tp,类_Dp>类 std::unique_ptr"的模板参数列表中参数 1 的类型/值不匹配
- OpenSSL fips in C++ wrapper Library 如何?错误:指纹不匹配
- 为什么我的数组值与此处的全局变量不匹配?
- 引号之间匹配/不匹配,带有不可避免的引号和多行
- 映射迭代器与运算符不匹配
- C++调用和定义不匹配
- 原型与decltype和auto不匹配