具有结构化绑定的不同 cv 限定符

Different cv-qualifiers with structured bindings

C++17 中的 structured binding declaration 允许多个不同的选项,例如:

std::tuple<int, int> foo();

auto  [a, b] = foo(); // a and b are: int
const auto  [a, b] = foo(); // a and b are: int const
const auto& [a, b] = foo(); // a and b are: int const&

有没有办法给 ab 不同的 cv 限定符?例如 a 的类型为 intb 的类型为 int const?

否 - proposal 的问答中对此进行了介绍:

Should the syntax be extended to allow const/&-qualifying individual names’ types?

auto [& x, const y, const& z] = f(); // NOT proposed

我们认为答案应该是否定的。这是一个存储值并将名称绑定到其组件的简单功能, 不要声明多个变量。允许这样的资格将是功能蠕变,将功能扩展到 是不同的东西,即声明多个变量的方法。 如果我们确实要声明多个变量,我们已经有拼法了:

auto val = f(); // or auto&&
T1& x = get<0>(val);
T2 const y = get<1>(val);
T3 const& z = get<2>(val);

这是不允许的,但似乎对结构化绑定的工作原理存在一些误解。以下是您的代码段的实际工作方式:

std::tuple<int, int> foo();

auto  [a, b] = foo(); // `a` and `b` are `int`
auto& [a, b] = foo(); // error: cannot bind a non-const lvalue-ref to an rvalue.
const auto  [a, b] = foo(); // `a` and `b` are: `int const`
const auto& [a, b] = foo(); // `a` and `b` are: `int const`! (NOT `int const&`)
                            // lifetime extension of `foo()` via `const&`.

根据您给出的示例,错误似乎在于认为 auto [a, b] 中的 auto 分布在变量中 。它不是。 auto 实际上是初始化器的类型。在 C++ 中,这大致是这样编码的:

auto temp = foo();  // `auto` is for the initializer!
// These aren't actually references, but close.
auto&& a = std::get<0>(temp);
auto&& b = std::get<1>(temp);

这与以下内容相反:

auto&& temp = foo();  // save `temp` like range-based `for` does!
// if `auto` in `auto [a, b]` were distributive.
auto a = std::get<0>(temp);
auto b = std::get<1>(temp);