C++中tuple元組的基本用法


轉載至https://blog.csdn.net/sevenjoin/article/details/88420885

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, T2, 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>
    2. 如何獲取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
    3.如何獲取元素的值

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

Ith - 是想獲取的元素在tuple對象中的位置。

obj - 是想獲取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';

//獲取元素
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) << " "; //將引發編譯錯誤
4.獲取元素的類型

 要想得到元素類型可以通過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
 5.利用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, 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 = 110;

std::tie(name, ages, std::ignore, std::ignore) = 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: , ages: 25, areaCode: 110
   6. tuple元素的引用

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

#include <iostream>
#include <tuple>
#include <functional>

int main(int argc, char **agrv) {

std::tuple<std::string, int, 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM