Wang's blog

元组与结构化绑定

Published on

元组

有时需要将多个不同类型的变量聚合为一个新类型,虽然使用类或结构体即可实现此功能,但是它们都需要提前声明并指定一个类型名称。很多情况下用户并不会重复使用该类型,或者并不关心该类型的名称,但是希望能够更加简单地实现该功能。为了解决此问题,C++11中引入了元组。元组类模板std::tuple是固定大小的异类值汇集。它是std::pair的泛用形式。

std::tuple<int, std::string, double> t1;                    // 用默认值初始化
std::tuple<int, std::string, double> t2{42, "Test", -3.14}; // 列表初始化
std::tuple<char, std::string, int> t3{t2};                  // 隐式转换
std::tuple<int, double> t4{std::make_pair(42, 3.14)};       // 从pair创建
auto t5 = std::make_tuple(1, 2.0f, 3.14, "string");         // 使用make_tuple创建
auto t6 = std::tuple_cat(t1, t2, t3);                       // 拼接元组

int size = std::tuple_size<decltype(t1)>::value;            // 获取元素个数

int a = std::get<0>(t1);                                    // 提取单个元素
std::get<0>(t1) = 0;                                        // 修改单个元素

int a1;
std::string b1;
double c1;
std::tie(a1, b1, c1) = t1;                                  // 解包元素
const auto [a2, b2, c2] = t2;                               // 结构化绑定

结构化绑定

结构化绑定用于将一组变量绑定至一个复合结构的所有子元素上,该复合结构可以为数组、元组或结构体。虽然也可以使用赋值语句逐一进行绑定,但是结构化绑定极大地简化了这一操作。

// 绑定数组
int arr[2] = {1, 2};
auto [xv, yv] = arr;            // 绑定元素值
auto &[xr, yr] = arr;           // 绑定元素引用

// 绑定元组
float x{};
char y{};
int z{};
std::tuple<float &, char &&, int> tpl(x, std::move(y), z);
const auto &[a, b, c] = tpl;    // a绑定至x,类型为float&;b绑定至y,类型为char&&;c绑定至tpl第3元素,类型为const int

// 绑定结构体
struct S
{
    mutable int x1;
    volatile double y1;
};
S f() { return S{1, 2.3}; }
const auto [xx, yy] = f();      // xx类型为int,yy类型为const volatile double