C++11 標準新引入了一種類模板,命名為 tuple(元組)。tuple 最大的特點是:實例化的對象可以存儲任意數量、任意類型的數據。 tuple 的應用場景很廣泛,例如當需要存儲多個不同類型的元素時,可以使用 tuple;當函數需要返回多個數據時,可以將這些數據存儲在 tuple 中,函數只需返 ...
C++11 標準新引入了一種類模板,命名為 tuple(元組)。tuple 最大的特點是:實例化的對象可以存儲任意數量、任意類型的數據。
tuple 的應用場景很廣泛,例如當需要存儲多個不同類型的元素時,可以使用 tuple;當函數需要返回多個數據時,可以將這些數據存儲在 tuple 中,函數只需返回一個 tuple 對象即可。
1. tuple對象的創建
tuple 本質是一個以可變模板參數定義的類模板,它定義在
#include <tuple>
using std::tuple;
實例化 tuple 模板類對象常用的方法有兩種,一種是藉助該類的構造函數,另一種是藉助 make_tuple() 函數。
1.1 類的構造函數
tuple 模板類提供有很多構造函數,包括:
1) 預設構造函數
constexpr tuple();
2) 拷貝構造函數
tuple (const tuple& tpl);
3) 移動構造函數
tuple (tuple&& tpl);
4) 隱式類型轉換構造函數
template <class... UTypes>
tuple (const tuple<UTypes...>& tpl); //左值方式
template <class... UTypes>
tuple (tuple<UTypes...>&& tpl); //右值方式
5) 支持初始化列表的構造函數
explicit tuple (const Types&... elems); //左值方式
template <class... UTypes>
explicit tuple (UTypes&&... elems); //右值方式
6) 將pair對象轉換為tuple對象
template <class U1, class U2>
tuple (const pair<U1,U2>& pr); //左值方式
template <class U1, class U2>
tuple (pair<U1,U2>&& pr); //右值方式
舉個例子:
#include <iostream> // std::cout
#include <tuple> // std::tuple
using std::tuple;
int main()
{
std::tuple<int, char> first; // 1) first{}
std::tuple<int, char> second(first); // 2) second{}
std::tuple<int, char> third(std::make_tuple(20, 'b')); // 3) third{20,'b'}
std::tuple<long, char> fourth(third); // 4)的左值方式, fourth{20,'b'}
std::tuple<int, char> fifth(10, 'a'); // 5)的右值方式, fifth{10.'a'}
std::tuple<int, char> sixth(std::make_pair(30, 'c')); // 6)的右值方式, sixth{30,''c}
return 0;
}
1.2 make_tuple()函數
上面程式中,我們已經用到了 make_tuple() 函數,它以模板的形式定義在
對於 make_tuple() 函數創建了 tuple 對象,我們可以上面程式中那樣作為移動構造函數的參數,也可以這樣用:
auto first = std::make_tuple (10,'a'); // tuple < int, char >
const int a = 0; int b[3];
auto second = std::make_tuple (a,b); // tuple < int, int* >
程式中分別創建了 first 和 second 兩個 tuple 對象,它們的類型可以直接用 auto 表示。
2. tuple常用函數
為了方便在實際開發中使用 tuple 對象,tupe 模板類提供了一個功能實用的成員函數,
函數或類模板 | 描 述 |
---|---|
tup1.swap(tup2) swap(tup1, tup2) | tup1 和 tup2 表示類型相同的兩個 tuple 對象,tuple 模板類中定義有一個 swap() 成員函數, |
get |
tup 表示某個 tuple 對象,num 是一個整數,get() 是 |
tuple_size |
tuple_size 是定義在 |
tuple_element<I, type>::type | tuple_element 是定義在 |
forward_as_tuple<args...> | args... 表示 tuple 對象存儲的多個元素,該函數的功能是創建一個 tuple 對象,內部存儲的 args... 元素都是右值引用形式的。 |
tie(args...) = tup | tup 表示某個 tuple 對象,tie() 是 |
tuple_cat(args...) | args... 表示多個 tuple 對象,該函數是 |
tuple 模板類對賦值運算符 = 進行了重載,使得同類型的 tuple 對象可以直接賦值。此外,tuple 模板類還重載了 ==、!=、<、>、>=、<= 這幾個比較運算符,同類型的 tuple 對象可以相互比較(逐個比較各個元素)。
以下程式演示了上表中一部分函數模板和類模板的功能:
#include <iostream>
#include <tuple>
int main()
{
int size;
//創建一個 tuple 對象存儲 10 和 'x'
std::tuple<int, char> mytuple(10, 'x');
//計算 mytuple 存儲元素的個數
size = std::tuple_size<decltype(mytuple)>::value;
//輸出 mytuple 中存儲的元素
std::cout << std::get<0>(mytuple) << " " << std::get<1>(mytuple) << std::endl;
//修改指定的元素
std::get<0>(mytuple) = 100;
std::cout << std::get<0>(mytuple) << std::endl;
//使用 makde_tuple() 創建一個 tuple 對象
auto bar = std::make_tuple("test", 3.1, 14);
//拆解 bar 對象,分別賦值給 mystr、mydou、myint
const char* mystr = nullptr;
double mydou;
int myint;
//使用 tie() 時,如果不想接受某個元素的值,實參可以用 std::ignore 代替
std::tie(mystr, mydou, myint) = bar;
//std::tie(std::ignore, std::ignore, myint) = bar; //只接收第 3 個整形值
//將 mytuple 和 bar 中的元素整合到 1 個 tuple 對象中
auto mycat = std::tuple_cat(mytuple, bar);
size = std::tuple_size<decltype(mycat)>::value;
std::cout << size << std::endl;
return 0;
}
程式執行結果為:
10 x
100
5