這次要講的內(nèi)容是:c++11中的tuple(元組)。tuple看似簡單,其實(shí)它是簡約而不簡單,可以說它是c++11中一個(gè)既簡單又復(fù)雜的東東,關(guān)于它簡單的一面是它很容易使用,復(fù)雜的一面是它內(nèi)部隱藏了太多細(xì)節(jié),要揭開它神秘的面紗時(shí)又比較困難。
tuple是一個(gè)固定大小的不同類型值的集合,是泛化的std::pair。和c#中的tuple類似,但是比c#中的tuple強(qiáng)大得多。我們也可以把他當(dāng)做一個(gè)通用的結(jié)構(gòu)體來用,不需要創(chuàng)建結(jié)構(gòu)體又獲取結(jié)構(gòu)體的特征,在某些情況下可以取代結(jié)構(gòu)體使程序更簡潔,直觀。
構(gòu)造一個(gè)tuple
tuple<const char*, int>tp = make_tuple(sendPack,nSendSize); //構(gòu)造一個(gè)tuple
這個(gè)tuple等價(jià)于一個(gè)結(jié)構(gòu)體
用tuple<const char*, int>tp就可以不用創(chuàng)建這個(gè)結(jié)構(gòu)體了,而作用是一樣的,是不是更簡潔直觀了。還有一種方法也可以創(chuàng)建元組,用std::tie,它會創(chuàng)建一個(gè)元組的左值引用。
auto tp = return std::tie(1, "aa", 2);//tp的類型實(shí)際是:std::tuple<int&,string&, int&>
再看看如何獲取它的值:
const char* data = tp.get<0>(); //獲取第一個(gè)值int len = tp.get<1>(); //獲取第二個(gè)值
還有一種方法也可以獲取元組的值,通過std::tie解包tuple
int x,y;string a;std::tie(x,a,y) = tp;
通過tie解包后,tp中三個(gè)值會自動賦值給三個(gè)變量。
解包時(shí),我們?nèi)绻幌虢饽硞€(gè)位置的值時(shí),可以用std::ignore占位符來表示不解某個(gè)位置的值。比如我們只想解第三個(gè)值時(shí):
std::tie(std::ignore,std::ignore,y) = tp; //只解第三個(gè)值了
還有一個(gè)創(chuàng)建右值的引用元組方法:forward_as_tuple。
std::map<int, std::string> m;m.emplace(std::forward_as_tuple(10, std::string(20, 'a')));
它實(shí)際上創(chuàng)建了一個(gè)類似于std::tuple<int&&, std::string&&>類型的tuple。
我們還可以通過tuple_cat連接多個(gè)tupe
輸出結(jié)果:
(10, Test, 3.14, Foo, bar, 10, Test, 3.14, 10)
到這里tuple的用法介紹完了,是不是很簡單,也很容易使用,相信你使用它之后就離不開它了。我前面說過tuple是簡約而不簡單。它有很多高級的用法。它和模板元關(guān)系密切,要介紹它的高級用法的時(shí)候,讀者需要一定的模板元基礎(chǔ),如果你只是把它當(dāng)一個(gè)泛型的pair去使用時(shí),這部分可以不看,如果你想用它高級用法的時(shí)候就往下看。讓我們要慢慢揭開tuple神秘的面紗。
通過std::tuple_element獲取元素類型。
template<typename Tuple>void Fun(Tuple& tp){std::tuple_element<0,Tuple>::type first = std::get<0> (mytuple);std::tuple_element<1,Tuple>::type second = std::get<1> (mytuple);}
因?yàn)閠uple的參數(shù)是變長的,也沒有for_each函數(shù),如果我們想遍歷tuple中的每個(gè)元素,需要自己寫代碼實(shí)現(xiàn)。比如我要打印tuple中的每個(gè)元素。
看到這里,想必大家對tuple有了一個(gè)全面的認(rèn)識了吧,怎么樣,它是簡約而不簡單吧。對模板元不熟悉的童鞋可以不看tuple高級用法部分,不要為看不懂而捉急,沒事的,高級部分一般用不到,知道基本用法就夠用了。
tuple和vector比較:
vector只能容納同一種類型的數(shù)據(jù),tuple可以容納任意類型的數(shù)據(jù);
vector和variant比較:
二者都可以容納不同類型的數(shù)據(jù),但是variant的類型個(gè)數(shù)是固定的,而tuple的類型個(gè)數(shù)不是固定的,是變長的,更為強(qiáng)大。
c++11 boost技術(shù)交流群:296561497,歡迎大家來交流技術(shù)。