为什么 const 按值结构绑定允许用户修改引用的变量?

Why const by-value structural binding allows the user to modify referenced variable?

我对结构绑定很困惑。即使我使用 const 和按值(没有 &)结构绑定,如本例所示:

#include <iostream>
#include <tuple>

int main()
{
    int x = 0;
    std::tuple<int&> p(x);
    const auto [a] = p;
    a++;
    std::cout << x << '\n';
}

它仍然修改x并打印1https://gcc.godbolt.org/z/jc8hxE8M6

如果我在 [a] 之前添加 & 或删除 const,您能否解释一下为什么它会这样工作并希望更改?

参见 cppreference 上的示例:

The portion of the declaration preceding [ applies to the hidden variable e, not to the introduced identifiers.

int a = 1, b = 2;
const auto& [x, y] = std::tie(a, b); // x and y are of type int&
auto [z, w] = std::tie(a, b);        // z and w are still of type int&
assert(&z == &a);                    // passes

其中e指的是

A structured binding declaration first introduces a uniquely-named variable (here denoted by e) to hold the value of the initializer, as follows: [...]

您示例中的 const 不适用于 a,下一个示例说明了为什么它仍然有用:

int a = 1;
const auto& [x] = std::make_tuple(a); // OK, not dangling
auto&       [y] = std::make_tuple(a); // error, cannot bind auto& to rvalue std::tuple
auto&&      [z] = std::make_tuple(a); // also OK

编译器推导出类似下面的类型

typedef int & Ref;

这是std::tuple对象的元素类型。

如果你会再写例如

int x = 0;
const Ref rx = x; 

那么最后一个声明等同于

int & const rx = x;

但与指针相反,在这个意义上,引用可能不是常量。所以限定符 const 被忽略了,你有

int & rx = x;

这是一个演示程序。

#include <tuple>
#include <type_traits>

int main()
{
    int x = 0;

    std::tuple<int &> p( x );
    const auto [a] = p;
    std::cout << std::is_same_v<decltype( a ), int &> << '\n';

    std::tuple<int *> p1( &x );
    const auto [b] = p1;
    std::cout << std::is_same_v<decltype( b ), int * const> << '\n';
}

程序输出为

1
1