为什么auto在使用结构化绑定时似乎会推断出引用?

s3r*_*vac 12 c++ c++17 structured-bindings

请考虑以下使用C++ 17结构化绑定的代码:

int a = 0, b = 0;
auto [x, y] = std::tie(a, b);
y = 1;
std::cout << a << ' ' << b << '\n';
Run Code Online (Sandbox Code Playgroud)

由于我使用auto,我希望的代码打印0 0y应该是一个拷贝.然而,它打印0 1.为什么?我认为裸露auto从不推断参考.

s3r*_*vac 19

正如cppreference所指出的那样,前面的声明部分[(即auto在您的情况下)不适用于引入的标识符.相反,它适用于由编译器在封面下创建的隐藏变量.您的结构化绑定声明

auto [x, y] = std::tie(a, b);
Run Code Online (Sandbox Code Playgroud)

大致相当于

auto e = std::tie(a, b);
decltype(std::get<0>(e)) x = std::get<0>(e);
decltype(std::get<1>(e)) y = std::get<1>(e);
Run Code Online (Sandbox Code Playgroud)

如您所见,auto应用于隐藏变量e而不是声明xy.类型estd::tuple<int&, int&>,并decltype(std::get<1>(e))给你int&.

  • 这里`decltype`的用法略有不正确.元组的`std :: get`总是返回一个引用(允许改变元组元素),但是`auto [x] = std :: tuple <int>(5)`将推导出`int`,而不是`int&`.这里的正确类型是`tuple_element_t <0,decltype(e)>` (4认同)
  • @Revolver_Ocelot`x`是隐藏变量成员的别名.从这个意义上说___is___是一个参考.虽然`decltype`有特殊处理,但它不像参考. (3认同)