通过类比理解C++ 17中的结构化绑定

Lin*_*gxi 9 c++ c++17 structured-bindings

我试图理解在C++ 17中引入的结构化绑定.关于cppreference的解释对我来说并不明显,但它看起来像

cv-auto ref-operator [x, y, z] = ...
Run Code Online (Sandbox Code Playgroud)

大致相当于(不考虑数组的情况)

cv-auto ref-operator unique_name = ...
#define x unique_name.member_a
#define y unique_name.member_b
#define z unique_name.member_c
Run Code Online (Sandbox Code Playgroud)

这里的关键点x y z是不是独立定义的变量,而只是返回值成员的别名.并cv-auto ref-operator适用于返回值,而不是别名(语法可能会误导这里).例如,请参阅cppreference示例

float x{};
char  y{};
int   z{};

std::tuple<float&,char&&,int> tpl(x,std::move(y),z);
const auto& [a,b,c] = tpl;
// a names a structured binding of type float& that refers to x
// b names a structured binding of type char&& that refers to y
// c names a structured binding of type const int that refers to the 3rd element of tpl
Run Code Online (Sandbox Code Playgroud)

如果a b c是独立定义的变量,const auto&应用于它们,c则不能是类型const int.

从实际的角度来看,这个类比未能抓住的关键点是什么?

MSa*_*ers 7

从另一个角度考虑这一点可能是有见地的.

在C++中,我们已经有变量,具有名称的int a = 5对象和不是变量的对象,并且没有名称:*new int.结构化绑定是一种为变量的所有部分创建名称的方法,而整个变量没有明确的名称.所以,它的组合[x,y,z]共同的名字有三个成员的变量.

重要的是,它们一起命名一个对象,因此编译器实际上必须布局该对象.独立变量可以独立放置在堆栈上.但是对于结构化绑定,编译器不能这样做(正常as-if规则除外)

因此,当我们将组合[x y z]视为变量的名称时,显然auto const& [x y z]使组合成为const&变量.

然后,我们必须考虑究竟是什么个人的名字x,yz意思.您的问题总结为

cv-auto ref-operator unique_name = ...
#define x unique_name.member_a
#define y unique_name.member_b
#define z unique_name.member_c
Run Code Online (Sandbox Code Playgroud)

这有点棘手.哪里member_a来的?它似乎unique_name有一个member_a.您已经排除了具有的数组大小写[0].元组有get<0>(tpl).可能很有可能member_a背后get<0>,但名称 member_a 可能是私人的.member_a也可能不那么符合常规get<0>.

但是,是的,对于最简单的情况,一个简单的struct没有位域,确实会有相应的member_a.