1. 程式人生 > 程式設計 >C++ tuple元組的基本用法(總結)

C++ tuple元組的基本用法(總結)

1,元組簡介

tuple是一個固定大小的不同型別值的集合,是泛化的std::pair。我們也可以把他當做一個通用的結構體來用,不需要建立結構體又獲取結構體的特徵,在某些情況下可以取代結構體使程式更簡潔,直觀。std::tuple理論上可以有無數個任意型別的成員變數,而std::pair只能是2個成員,因此在需要儲存3個及以上的資料時就需要使用tuple元組了。

tuple(元組)在c++11中開始引用的。tuple看似簡單,其實它是簡約而不簡單,可以說它是c++11中一個既簡單又複雜的東東,關於它簡單的一面是它很容易使用,複雜的一面是它內部隱藏了太多細節,要揭開它神祕的面紗時又比較困難。

2,tuple的建立和初始化

 std::tuple<T1,T2,TN> t1;  //建立一個空的tuple物件(使用預設構造),它對應的元素分別是T1和T2...Tn型別,採用值初始化。
std::tuple<T1,TN> t2(v1,v2,... TN); //建立一個tuple物件,它的兩個元素分別是T1和T2 ...Tn型別; 要獲取元素的值需要通過tuple的成員get<Ith>(obj)進行獲取(Ith是指獲取在tuple中的第幾個元素,請看後面具體例項)。
std::tuple<T1&> t3(ref&); // tuple的元素型別可以是一個引用
std::make_tuple(v1,v2); // 像pair一樣也可以通過make_tuple進行建立一個tuple物件

tuple的元素型別為引用:

std::string name;
std::tuple<string &,int> tpRef(name,30);
// 對tpRef第一個元素賦值,同時name也被賦值 - 引用
std::get<0>(tpRef) = "Sven";
 
// name輸出也是Sven
std::cout << "name: " << name << '\n';

3,有關tuple元素的操作

等價結構體

開篇講過在某些時候tuple可以等同於結構體一樣使用,這樣既方便又快捷。如:

struct person {
 char *m_name;
 char *m_addr;
 int *m_ages;
};
 
//可以用tuple來表示這樣的一個結構型別,作用是一樣的。
std::tuple<const char *,const char *,int>

如何獲取tuple元素個數

當有一個tuple物件但不知道有多少元素可以通過如下查詢:

// tuple_size
#include <iostream> // std::cout
#include <tuple> // std::tuple,std::tuple_size
 
int main ()
{
 std::tuple<int,char,double> mytuple (10,'a',3.14);
 
 std::cout << "mytuple has ";
 std::cout << std::tuple_size<decltype(mytuple)>::value;
 std::cout << " elements." << '\n';
 
 return 0;
}
 
//輸出結果:
mytuple has 3 elements

如何獲取元素的值

獲取tuple物件元素的值可以通過get<Ith>(obj)方法進行獲取;

Ith - 是想獲取的元素在tuple物件中的位置。

obj - 是想獲取tuple的物件

// tuple_size
#include <iostream> // std::cout
#include <tuple> // std::tuple,3.14);
 
 std::cout << "mytuple has ";
 std::cout << std::tuple_size<decltype(mytuple)>::value;
 std::cout << " elements." << '\n';
 
 //獲取元素
 std::cout << "the elements is: ";
 std::cout << std::get<0>(mytuple) << " ";
 std::cout << std::get<1>(mytuple) << " ";
 std::cout << std::get<2>(mytuple) << " ";
 
 std::cout << '\n';
 
 return 0;
}
 
//輸出結果:
mytuple has 3 elements.
the elements is: 10 a 3.14 

tuple不支援迭代,只能通過元素索引(或tie解包)進行獲取元素的值。但是給定的索引必須是在編譯器就已經給定,不能在執行期進行動態傳遞,否則將發生編譯錯誤:

for(int i=0; i<3; i++)
 std::cout << std::get<i>(mytuple) << " "; //將引發編譯錯誤

獲取元素的型別

要想得到元素型別可以通過tuple_element方法獲取,如有以下元組物件:

std::tuple<std::string,int> tp("Sven",20);
 
// 得到第二個元素型別
 
std::tuple_element<1,decltype(tp)>::type ages; // ages就為int型別
 
ages = std::get<1>(tp);
 
std::cout << "ages: " << ages << '\n';
 
//輸出結果: 
ages: 20

利用tie進行解包元素的值

如同pair一樣也是可以通過tie進行解包tuple的各個元素的值。如下tuple物件有4個元素,通過tie解包將會把這4個元素的值分別賦值給tie提供的4個變數中。

#include <iostream>
#include <tuple>
#include <utility>
 
int main(int argc,char **argv) {
 std::tuple<std::string,int,std::string,int> tp;
 tp = std::make_tuple("Sven",25,"Shanghai",21);
 
 // 定義接收變數
 std::string name;
 std::string addr;
 int ages;
 int areaCode;
 
 std::tie(name,ages,addr,areaCode) = tp;
 std::cout << "Output: " << '\n';
 std::cout << "name: " << name <<",";
 std::cout << "addr: " << addr << ",";
 std::cout << "ages: " << ages << ",";
 std::cout << "areaCode: " << areaCode << '\n';
 
 return 0;
}
//輸出結果:
Output: 
name: Sven,addr: Shanghai,ages: 25,areaCode: 21

但有時候tuple包含的多個元素時只需要其中的一個或兩個元素,如此可以通過std::ignore進行變數佔位,這樣將會忽略提取對應的元素。可以修改上述例程:

#include <iostream>
#include <tuple>
#include <utility>
 
int main(int argc,21);
 
 // 定義接收變數
 std::string name;
 std::string addr;
 int ages;
 int areaCode = 110;
 
 std::tie(name,std::ignore,std::ignore) = tp;
 std::cout << "Output: " << '\n';
 std::cout << "name: " << name <<",";
 std::cout << "areaCode: " << areaCode << '\n';
 
 return 0;
}
 
//輸出結果:
Output: 
name: Sven,addr:,areaCode: 110

tuple元素的引用

前面已經列舉了將引用作為tuple的元素型別。下面通過引用搭配make_tuple()可以提取tuple的元素值,將某些變數值設給它們,並通過改變這些變數來改變tuple元素的值:

#include <iostream>
#include <tuple>
#include <functional>
 
int main(int argc,char **agrv) {
 
 std::tuple<std::string,float> tp1("Sven Cheng",77,66.1);
 
 std::string name;
 int weight;
 float f;
 
 auto tp2 = std::make_tuple(std::ref(name),std::ref(weight),std::ref(f)) = tp1;
 
 std::cout << "Before change: " << '\n';
 std::cout << "name: " << name << ",";
 std::cout << "weight: " << weight << ",";
 std::cout << "f: " << f << '\n';
 
 name = "Sven";
 weight = 80;
 f = 3.14;
 
 std::cout << "After change: " << '\n';
 std::cout << "element 1st: " << std::get<0>(tp2) << ",";
 std::cout << "element 2nd: " << std::get<1>(tp2) << ",";
 std::cout << "element 3rd: " << std::get<2>(tp2) << '\n';
 
 return 0;
}
 
//輸出結果:
Before change: 
name: Sven Cheng,weight: 77,f: 66.1
After change: 
element 1st: Sven,element 2nd: 80,element 3rd: 3.14

tuple交換

tuple<int,float> t4(11,"Test",3.14);
cout << get<0>(t3) << " " << get<0>(t4) << endl;
t3.swap(t4); 
cout << get<0>(t3) << " " << get<0>(t4) << endl;

排序

bool cmp(tuple<string,char> a,tuple<string,char> b){
 return a<b;
 return get<1>(a)<get<1>(b); // 也可以按某列排序
}
main(){
 tuple<string,char> my_tuple[10];
 my_tuple[0] = std::make_tuple ("Pipr",42,'a');
 my_tuple[1] = std::make_tuple ("Piper",41,'a');
 my_tuple[2] = std::make_tuple ("Pper",45,'a');
 my_tuple[3] = std::make_tuple ("Pier",49,'a');
 for(int i=0;i<4;++i){
 cout << get<0>(my_tuple[i]) << " " << get<1>(my_tuple[i]) << " ";
 }
 cout << endl;
 sort(my_tuple,my_tuple+4,cmp);
 for(int i=0;i<4;++i){
 cout << get<0>(my_tuple[i]) << " " << get<1>(my_tuple[i]) << " ";
 }
 cout << endl;
}

到此這篇關於C++ tuple元組的基本用法(總結)的文章就介紹到這了,更多相關C++ tuple元組內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!