C++17 特性之结构化绑定(一):概述

C++17新增一项非常方便有用的特性:
结构化绑定(即Structured Bindings)。
假设你定义了一个结构体,包含2个不同类型的成员:

struct MyStruct {

    int i = 0;

    std::string s;

};


MyStruct ms;

在C++17中,你可以直接将该结构体的2个成员绑定到新的名字上去:

auto [u,v] = ms;

这里变量名 u
v
就是所谓的结构化绑定。这种用法分解了传过来并初始化用的对象,有时也被称为分解式声明。
结构化绑定对于函数返回结构体或数组时特别有用。例如,你有一个函数要返回一个结构体:

MyStruct getStruct() {

    return MyStruct{42, "hello"};

}

你就可以直接将函数返回值的2个成员变量赋值给2个局部变量:

auto [id,val] = getStruct(); // id和val对应返回的结构体中的i和s

这里 id
val
就是返回的结构体成员变量 i
s
。他们拥有相同的类型,即
int


std::string

,并且可以当作两个不同的对象使用:

if (id > 30) {

    std::cout << val;

}

这样的好处是可以直接访问到成员变量,而且得益于将成员变量绑定到新的名字上去,从而更好地表达它们的原有的含义,使得代码更具有可读性。

下面的代码演示了结构化绑定如何使得代码获得巨大的提升。在没有结构化绑定的年代,为了迭代
std::map

中的元素,代码要这么写:

for (const auto& elem : mymap) {

    std::cout << elem.first << ": " << elem.second << '\n';

}

其中元素类型是
std::pair

,包含一个
key

类型和一个
value

类型,也就是
std::pair

first
成员和 second
成员,你就得用这2个名字来访问
key


value

。但是有了结构化绑定,代码就可以写得具有更好的可读性:

for (const auto& [key,val] : mymap) {

    std::cout << key << ": " << val << '\n';

}

我们直接就用 key
value
这两个名字来访问每个成员,这两个名字清楚地表达了它们的含义。
请继续关注本公众号下一节《C++17特性:结构化绑定(二)细解》。