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