Video Link: C++ Weekly - Ep 24 C++17’s Structured Bindings
Verification Case
结构化绑定是一个比较有意思的功能,从某个角度来看,使用{}
可以将数据打包成tuple
/array
/class
等,结构化绑定便是使用auto []
将以打包的数据展开。举个最常见的例子[1]:
1
2
3
4
5
6
7
| int main() {
std::set<std::string> myset;
if (auto it = myset.insert("Hello"); it->second)
std::cout << "insert is successful. The value is " << std::quoted(*iter->first) << '\n';
else
std::cout << "The value " << std::quoted(*iter->first) << " already exists in the set\n";
}
|
使用结构化绑定具名iter
、success
,代码表述能力更强,也更为精炼。
1
2
3
4
5
6
7
| int main() {
std::set<std::string> myset;
if (auto [iter, success] = myset.insert("Hello"); success)
std::cout << "insert is successful. The value is " << std::quoted(*iter) << '\n';
else
std::cout << "The value " << std::quoted(*iter) << " already exists in the set\n";
}
|
结构化绑定array
1
2
3
4
5
6
7
8
| TEST(StructuredBindingDeclarationArray, Value) {
int a[2] = {1, 2};
auto [x, y] = a;
ASSERT_EQ(x, 1);
ASSERT_EQ(y, 2);
ASSERT_NE(&x, a);
ASSERT_NE(&y, std::next(a));
}
|
将数组中的每个元素具名绑定。上述为值绑定,引用绑定可以定义为auto& [x, y] = a;
或万能引用auto&& [x, y] = a;
,const
引用绑定添加const
修饰符即可,如const auto& [x, y] = a;
。[
前的所有修饰符便像是修饰[]
中的每个元素一样,这也是通常性的思维。
结构化绑定struct
/tuple
/pair
…
1
2
3
4
5
6
7
8
9
10
11
12
13
| std::tuple<float&, int, char&&> baseline();
TEST_F(StructuredBindingDeclarationTuple, RValue) {
auto [x, y, z] = this->baseline();
ASSERT_TRUE((std::is_lvalue_reference_v<decltype(x)>));
ASSERT_FALSE((std::is_rvalue_reference_v<decltype(x)>));
ASSERT_FALSE((std::is_lvalue_reference_v<decltype(y)>));
ASSERT_FALSE((std::is_rvalue_reference_v<decltype(y)>));
ASSERT_FALSE((std::is_lvalue_reference_v<decltype(z)>));
ASSERT_TRUE((std::is_rvalue_reference_v<decltype(z)>));
ASSERT_EQ(&x, &tx);
ASSERT_NE(&y, &ty);
ASSERT_EQ(y, 2);
}
|
其中值类型绑定时,const
以及引用特性与绑定array
场景下完全一致。而引用类型(lvalue
/rvalue
)绑定时,const
以及引用特性均无影响,即其类型在结构定义时确定,后续结构化绑定的所有修饰符均对其无效。如:std::tuple<float&, int, char&&>
,无论是auto [x, y, z]
、auto& [x, y, z]
亦或是const auto& [x, y, z]
,x
的type始终为非const
的左值引用,z
的type始终为非const
的右值引用,只有y
会受影响(同结构化绑定array
)。
注:完整的测试用例可以参考https://gitee.com/dreamonlysh/tony/blob/master/support/estd/unittest/structured_binding_declaration_test.cpp
参考资料
[1] Structured binding declaration. https://en.cppreference.com/w/cpp/language/structured_binding