我尝试在GCC 8.2下用不同的选项编译这个C++代码,它总是成功的,不会产生任何警告,并输出true
:
int && a = 123;
decltype(auto) b = a;
std::cout << std::boolalpha << std::is_same<decltype(b), int&>::value;
同时,相同的代码不会在Clang中编译,如果我对标准的理解是正确的,那就是符合标准的行为。
decltype
:上的cppreference
如果参数是未加括号的id表达式或未加括号类成员访问表达式,则decltype将生成由该表达式命名的实体的类型。
decltype(auto)
:上的cppreference
如果变量的声明类型是decltype(auto(,则关键字auto将替换为其初始值设定项的表达式(或表达式列表(,并使用decltype的规则推导实际类型。
因此,decltype(auto)
应该产生int&&
。由于a
是一个左值,它不应该绑定到b
,从而导致编译错误。
那么GCC是否不符合标准,或者我遗漏了什么?
你的推理是合理的。我想我看到GCC的困境了。
decltype(auto)
的措辞表示auto
被初始值设定项中的表达式替换。根据GCC,这意味着你的代码不等同于
decltype(a) b = a;
但它相当于
decltype((a)) b = a;
但这是错误的。初始值设定项是"一个未加括号的id表达式">,因此[dcl.type.simple]中针对未加括号id表达式的规则应正常应用。需要将CCD_ 10的类型推导为CCD_。
正如@Aconcagua所发现的,这是一个已知的GCC错误。