为什么"const auto [x,y]"在绑定到引用类型时不能按预期运行?

xml*_*lmx 18 c++ standards decltype c++17 structured-bindings

以下代码段摘自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&
Run Code Online (Sandbox Code Playgroud)

我的问题是在最后一行:

为什么 decltype(w) int& 不是 const int&

lub*_*bgr 15

Jarod42在评论中回答了问题的问题,让我在这里引用标准的相关部分,来自[dcl.struct.bind]¹:

给定由std :: tuple_element :: type指定的类型Ti,引入的变量具有使用初始化器([dcl.init.ref])初始化的"引用于Ti"类型的唯一名称ri,其中引用是如果初始化程序是左值,则为左值引用,否则为右值引用.每个vi是Ti类型的左值的名称,它引用绑定到ri的对象; 引用的类型是Ti.

因此,在const auto [z, w] = f();,你必须const T1T1正在intconst T2T2int&.当const修改左边的内容时,这就变成了int& const结果int&.

请注意,int& const变换int&只能在模板参数替换中使用,即,这不会编译:

int n = 42;
int& const doesntWork = n; // Error: 'const' qualifiers cannot be applied to 'int&'
Run Code Online (Sandbox Code Playgroud)

但这样做:

template <class T> void f(const T t)
{
   ++t;
}

int n = 42;

f<int&>(n);
Run Code Online (Sandbox Code Playgroud)

在从相同的收缩int& constint&如上述进行.

¹感谢@cpplearner指出我这里的确切段落.


Ala*_*les 5

它将是引用本身,而不是引用的const值.由于引用不可修改,因此不存在常量引用.