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特性:结构化绑定(二)细解》。