具有结构化绑定的不同 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&
有没有办法给 a
和 b
不同的 cv 限定符?例如 a
的类型为 int
和 b
的类型为 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);
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&
有没有办法给 a
和 b
不同的 cv 限定符?例如 a
的类型为 int
和 b
的类型为 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);