考虑一个例子:
#include <iostream>
#include <type_traits>
#include <tuple>
int main() {
auto tup = std::make_tuple(1, 2);
auto [ a, b ] = tup;
decltype(auto) e = a;
std::cout << std::boolalpha << std::is_reference_v<decltype(e)> << std::endl;
}
clang(输出:false
)和gcc(输出:true
)在这个简单的情况下不一致。记住,例如e
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
应该是参考还是gcc错误?或者代码可能不正确?
答案 0 :(得分:18)
标识符本身是引用。来自[dcl.struct.bind]/3:
给定由
std::tuple_element<i, E>::type
指定的类型T i ,每个v i 是“对T i 的引用类型的变量“使用初始化程序初始化,如果初始化程序是左值,则引用是左值引用,否则为右值引用;引用的类型是T i 。
也就是说,a
和b
都是int&&
。
但decltype(auto)
实际行为的方式来自[dcl.type.auto.deduct]:
如果占位符是
decltype(auto)
类型说明符,则T
应仅为占位符。T
推导出的类型按照[dcl.type.simple]中的描述确定,好像e
是decltype
的操作数。
这个措辞真的很尴尬,但最终:
decltype(auto) e = a;
~~~~~~~~~~~~~~
表示:
decltype( a ) e = a;
~~~~
和decltype(a)
表示来自[dcl.type.simple]/4.1:
如果
e
是未加密码的 id-expression 命名结构化绑定([dcl.struct.bind]),decltype(e)
引用的类型在结构化绑定声明的规范中给出;
a
的引用类型为int
,因此e
必须为int
。这意味着它不是参考,而且铿锵是正确的。提起81176。