以下代码片段摘自cppref:
std::tuple<int, int&> f();
auto [x, y] = f();
// decltype(x) is int
// decltype(y) is int&
const auto [z, w] = f();
// decltype(z) is const int
// decltype(w) is int&
我的问题在最后一行:
为什么是decltype(w)
int&
而不是const int&
Jarod42回答了评论中的问题,让我在这里引用标准的相关部分,来自[dcl.struct.bind]
给定std指定的类型Ti::元组元素::类型中,变量引入了使用初始化器([dcl.init.ref](初始化的"对Ti的引用"类型的唯一名称ri,其中,如果初始化器是左值,则引用是左值引用,否则是右值引用。每个vi是Ti类型的左值的名称,该左值指绑定到ri的对象;参考类型是Ti。
因此,在const auto [z, w] = f();
中,有const T1
,其中T1
是int
,const T2
,其中T2
是int&
。当const
修改它左边的内容时,它就变成了int& const
,并产生了int&
。
注意,int& const
变成int&
只有在模板参数替换中才可能,即这不会编译:
int n = 42;
int& const doesntWork = n; // Error: 'const' qualifiers cannot be applied to 'int&'
但这是:
template <class T> void f(const T t)
{
++t;
}
int n = 42;
f<int&>(n);
其中发生与上述相同的从CCD_ 16到CCD_。
cco感谢@cpplearner为我指出这里的确切段落。
它将是引用本身,而不是常量的引用值。由于引用无论如何都是不可修改的,所以不存在常量引用。