欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++11, 14, 17對(duì)tuple元素的訪問(wèn)詳情

 更新時(shí)間:2022年11月05日 09:58:07   作者:歪鍋鍋  
這篇文章主要介紹了C++11, 14, 17對(duì)tuple元素的訪問(wèn)詳情,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

C++11, 14, 17對(duì)tuple元素的訪問(wèn)

std::tuple 作為可以存放任意個(gè)數(shù),任意類型的元祖被我個(gè)人經(jīng)常使用。

記得以前看侯捷談到這個(gè)數(shù)據(jù)結(jié)構(gòu)的時(shí)候,被他的實(shí)現(xiàn)所驚奇,太巧妙地設(shè)計(jì)。

我自己在使用std::tuple的時(shí)候也隨著C++版本的更新嘗試新的寫法,對(duì)于元組中元素的獲取,我一直覺(jué)得很有意思:

比如我有這么一個(gè)源文件:

#include <iostream>
#include <tuple>

#define CPP11 (__cplusplus < 201401L)
#define CPP14 (__cplusplus < 201701L and __cplusplus > 201401L)
#define CPP17 (__cplusplus >= 201702L)

class Moo {
  Moo() { ::printf("%s\n", __PRETTY_FUNCTION__); }
  Moo(Moo const &) { ::printf("%s\n", __PRETTY_FUNCTION__); }
  Moo(Moo &&) { ::printf("%s\n", __PRETTY_FUNCTION__); }
  Moo &operator=(Moo const &) noexcept {
    ::printf("%s\n", __PRETTY_FUNCTION__);
    return *this;
  }

  Moo &operator=(Moo &&) noexcept {
    ::printf("%s\n", __PRETTY_FUNCTION__);
    return *this;
  }

  ~Moo() { ::printf("%s\n", __PRETTY_FUNCTION__); }
};

int main() {
  std::cout << "c++ version:" << __cplusplus << std::endl;
  auto &&tp = std::make_tuple<Moo, const char *, int>(Moo(), "hello world", 3);

#if CPP11
  auto &&first = std::get<0>(tp);
  auto &&second = std::get<1>(tp);
  auto &&third = std::get<2>(tp);
#endif

#if CPP14
  auto &&first = std::get<Moo>(tp);
  auto &&second = std::get<const char *>(tp);
  auto &&third = std::get<int>(tp);
#endif

#if CPP17
  auto [a, b, c] = tp;
  auto &[first, second, third] = tp;
#endif

  return 0;
}

Moo類考察當(dāng)前對(duì)象在構(gòu)造tuple和返回值的過(guò)程中經(jīng)歷怎樣的人生

  • C++11: 使用std::get方法來(lái)獲取對(duì)應(yīng)秩的元素的引用
  • C++14: 使用類似在nlohmannjson里面獲取對(duì)應(yīng)類型的json對(duì)象的方式,通過(guò)類型來(lái)獲取對(duì)應(yīng)的元素的引用,有點(diǎn)現(xiàn)代C++那味兒了吼
  • C++17: 引入了結(jié)構(gòu)化綁定,不實(shí)用引用的時(shí)候會(huì)返回新創(chuàng)建的臨時(shí)對(duì)象,a, b, c是對(duì)臨時(shí)對(duì)象的右值引用,而使用引用則是想std::get那樣引用原本對(duì)象。C++17結(jié)構(gòu)化綁定yyds!表達(dá)力比之前強(qiáng)太多

std::tuple大總結(jié)

C++11引入了一個(gè)新的較實(shí)用的模板類型,std::tuple,也即是元組。元組是一個(gè)固定大小的不同類型(異質(zhì),heterogeneous)值的集合,也即它可以同時(shí)存放不同類型的數(shù)據(jù)。

類似于python中用小括號(hào)表示的元組類型。C++已有的std::pair類型類似于一個(gè)二元組,可看作是std::tuple的一個(gè)特例,std::tuple也可看作是std::pair的泛化。std::pair的長(zhǎng)度限制為2,而std::tuple的元素個(gè)數(shù)為0~任意個(gè)。

元組的使用

  • 有時(shí)候希望將一些數(shù)據(jù)組合成單一對(duì)象,但又不想麻煩地定義一個(gè)新數(shù)據(jù)結(jié)構(gòu)來(lái)表示這些數(shù)據(jù)時(shí),std::tuple是非常有用的。我們可以將std::tuple看作一個(gè)“快速而隨意”的數(shù)據(jù)結(jié)構(gòu)。我們可以把它當(dāng)作一個(gè)通用的結(jié)構(gòu)體使用,但又不需要?jiǎng)?chuàng)建和獲取結(jié)構(gòu)體的特征,使得程序更加簡(jiǎn)潔直觀。
  • 創(chuàng)建一個(gè)std::tuple對(duì)象時(shí),可以使用tuple的默認(rèn)構(gòu)造函數(shù),它會(huì)對(duì)每個(gè)成員進(jìn)行值初始化;也可以為每個(gè)成員提供一個(gè)初始值,此時(shí)的構(gòu)造函數(shù)是explicit的,因此必須使用直接初始化方法。
  • 一個(gè)std::tuple類型的成員數(shù)目是沒(méi)有限制的,因此,元組的成員都是未命名的。要訪問(wèn)一個(gè)元組的成員,就要使用一個(gè)名為get的標(biāo)準(zhǔn)庫(kù)函數(shù)模板。為了使用get,我們必須指定一個(gè)顯式模板實(shí)參,它指出我們想要訪問(wèn)第幾個(gè)成員。我們傳遞給get一個(gè)tuple對(duì)象,它返回指定成員的引用。get尖括號(hào)中的值必須是一個(gè)整型常量表達(dá)式。與往常一樣,我們從0開(kāi)始計(jì)數(shù),意味著get<0>是第一個(gè)成員。
  • 為了使用tuple_size或tuple_element,我們需要知道一個(gè)元組對(duì)象的類型。與往常一樣,確定一個(gè)對(duì)象的類型的最簡(jiǎn)單方法就是使用decltype。
  • std::tuple的一個(gè)常見(jiàn)用途是從一個(gè)函數(shù)返回多個(gè)值。
  • std::tuple中元素是被緊密地存儲(chǔ)的(位于連續(xù)的內(nèi)存區(qū)域),而不是鏈?zhǔn)浇Y(jié)構(gòu)。
  • std::tuple實(shí)現(xiàn)了多元組,這是一個(gè)編譯期就確定大小的容器,可以容納不同類型的元素。多元組類型在當(dāng)前標(biāo)準(zhǔn)庫(kù)中被定義為可以用任意數(shù)量參數(shù)初始化的類模板。每一模板參數(shù)確定多元組中一元素的類型。所以,多元組是一個(gè)多類型、大小固定的值的集合。

典型使用

創(chuàng)建和初始化

{
? ? std::tuple<int, double, std::string> first; ? ?// 創(chuàng)建一個(gè)空的元組,需要指定元組元素的數(shù)據(jù)類型,調(diào)用各個(gè)成員的默認(rèn)構(gòu)造函數(shù)進(jìn)行初始化。
? ? std::tuple<int, double, std::string> second(first); ?// 拷貝構(gòu)造
? ? std::tuple<int, char> third(10, 'a'); ? ? ? ?// 創(chuàng)建并初始化,使用小括號(hào)初始化
? ? std::tuple<int, std::string, double> fourth{42, "Test", -3.14}; ?// 創(chuàng)建并初始化,使用新的大括號(hào)初始化列表方式初始化
? ? std::tuple<int, char> fifth(std::make_tuple(20, 'b')); ? ? // 移動(dòng)構(gòu)造,使用模板庫(kù)的make_tuple
? ? first = std::make_tuple(1, 3.14, "tuple"); ? ? ? // 移動(dòng)賦值
? ? int i_third = 3;
? ? std::tuple<int&> sixth(std::ref(i_third)); ? // 創(chuàng)建一個(gè)元組,元組的元素可以被引用
}?

元組的訪問(wèn)和修改 

std::get<N>()

{
? ? int n = 1;
? ? auto t = std::make_tuple(10, "Test", 3.14, std::ref(n), n);
? ? // get尖括號(hào)中的值必須是一個(gè)整型常量表達(dá)式。從0開(kāi)始計(jì)數(shù),意味著get<0>是第一個(gè)成員。
? ? std::cout << "The value of t is " ?<< "("
? ? ? ? ? ? ? ?<< std::get<0>(t) << ", " << std::get<1>(t) << ", "
? ? ? ? ? ? ? ?<< std::get<2>(t) << ", " << std::get<3>(t) << ", "
? ? ? ? ? ? ? ?<< std::get<4>(t) << ")\n";
? ? // 由于get返回指定元素的引用,所以可用來(lái)修改指定位置的元素的值。此處因?yàn)榈?個(gè)元素是引用類型,所以被引用的值也會(huì)改變
? ? std::get<3>(t) = 9;
? ? std::cout << n << std::endl;
}

元組的元素個(gè)數(shù)

使用std::tuple_size<>()

{
? ? std::tuple<char, int, long, std::string> first('A', 2, 3, "4");
? ? int i_count = std::tuple_size<decltype(first)>::value; ?// 使用std::tuple_size計(jì)算元組個(gè)數(shù)
? ? std::cout << "the number of elements of a tuple:" << i_count << "\n";
}

元組的解包

std::tie() 元組包含一個(gè)或者多個(gè)元素,使用std::tie解包: 首先需要定義對(duì)應(yīng)元素的變量,再使用tie。

{ // std::tie: function template, Constructs a tuple object whose elements are references
? // to the arguments in args, in the same order
? // std::ignore: object, This object ignores any value assigned to it. It is designed to be used as an
? // argument for tie to indicate that a specific element in a tuple should be ignored.
? ??
? ? int myint;
? ? char mychar;
?
? ? std::tuple<int, float, char> mytuple;
?
? ? mytuple = std::make_tuple(10, 2.6, 'a'); ? ? ? ? ?// packing values into tuple
?
? ? std::tie(myint, std::ignore, mychar) = mytuple; ? // unpacking tuple into variables
?
? ? std::cout << "myint contains: " << myint << '\n';
? ? std::cout << "mychar contains: " << mychar << '\n';
}

元組的元素類型獲取

獲取元組中某個(gè)元素的數(shù)據(jù)類型,需要用到另外一個(gè)類型: std::tuple_element。 語(yǔ)法: std::tuple_element<index, tuple>。

{
? ? std::tuple<int, std::string> third(9, std::string("ABC"));
? ??
? ? // 得到元組第1個(gè)元素的類型,用元組第一個(gè)元素的類型聲明一個(gè)變量
? ? std::tuple_element<1, decltype(third)>::type val_1;
? ??
? ? // 獲取元組的第一個(gè)元素的值
? ? val_1 = std::get<1>(third);
? ? std::cout << "val_1 = " << val_1.c_str() << "\n";
}

元組的拼接

使用 std::tuple_cat 執(zhí)行拼接

{
? ? std::tuple<char, int, double> first('A', 1, 2.2f);
? ? // 組合到一起, 使用auto, 自動(dòng)推導(dǎo)
? ? auto second = std::tuple_cat(first, std::make_tuple('B', std::string("-=+")));
? ? // 組合到一起,可以知道每一個(gè)元素的數(shù)據(jù)類型時(shí)什么 與 auto推導(dǎo)效果一樣
? ? std::tuple<char, int, double, char, std::string> third = std::tuple_cat(first, std::make_tuple('B', std::string("-=+")));
? ? // 輸出合并后的元組內(nèi)容
? ? int index = 0;
? ? std::cout << index++ << " = " << std::get<0>(second) << "\n"; ?// 0 = A
? ? std::cout << index++ << " = " << std::get<1>(second) << "\n"; ?// 1 = 1?
? ? std::cout << index++ << " = " << std::get<2>(second) << "\n"; ?// ?2 = 2.2
? ? std::cout << index++ << " = " << std::get<3>(second) << "\n"; ?// 3 = B
? ? std::cout << index++ << " = " << std::get<4>(second).c_str() << "\n"; // 4 = -=+
}

元組的遍歷

元組沒(méi)用提供operator []重載,遍歷起來(lái)較為麻煩,需要為其單獨(dú)提供遍歷模板函數(shù) 

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C語(yǔ)言文件讀寫操作介紹與簡(jiǎn)單示例

    C語(yǔ)言文件讀寫操作介紹與簡(jiǎn)單示例

    這篇文章主要給大家介紹了關(guān)于C語(yǔ)言文件讀寫操作的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • C++實(shí)現(xiàn)哈夫曼樹(shù)編碼解碼

    C++實(shí)現(xiàn)哈夫曼樹(shù)編碼解碼

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)哈夫曼樹(shù)編碼解碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C語(yǔ)言線性表中順序表超詳細(xì)理解

    C語(yǔ)言線性表中順序表超詳細(xì)理解

    程序中經(jīng)常需要將一組數(shù)據(jù)元素作為整體管理和使用,需要?jiǎng)?chuàng)建這種元素組,用變量記錄它們,傳進(jìn)傳出函數(shù)等。一組數(shù)據(jù)中包含的元素個(gè)數(shù)可能發(fā)生變化,順序表則是將元素順序地存放在一塊連續(xù)的存儲(chǔ)區(qū)里,元素間的順序關(guān)系由它們的存儲(chǔ)順序自然表示
    2022-03-03
  • C++實(shí)現(xiàn)本地TCP通訊的示例代碼

    C++實(shí)現(xiàn)本地TCP通訊的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C++如何利用TCP技術(shù),實(shí)現(xiàn)本地ROS1和ROS2的通訊,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • 線程崩潰不會(huì)導(dǎo)致?JVM?崩潰的原因解析

    線程崩潰不會(huì)導(dǎo)致?JVM?崩潰的原因解析

    網(wǎng)上看到一個(gè)很有意思的據(jù)說(shuō)是美團(tuán)的面試題:為什么線程崩潰崩潰不會(huì)導(dǎo)致?JVM?崩潰,這個(gè)問(wèn)題我看了不少回答,但都沒(méi)答到根本原因,所以決定答一答,相信大家看完肯定會(huì)有收獲,本文分以下幾節(jié)來(lái)探討,需要的朋友可以參考下
    2022-06-06
  • c語(yǔ)言實(shí)現(xiàn)奇偶排序算法

    c語(yǔ)言實(shí)現(xiàn)奇偶排序算法

    這篇文章主要介紹了c語(yǔ)言實(shí)現(xiàn)奇偶排序算法,有需要的朋友可以參考一下
    2013-12-12
  • C++/C 回文字符串的實(shí)例詳解

    C++/C 回文字符串的實(shí)例詳解

    這篇文章主要介紹了C++ 回文字符串的實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • C++變量判定的螺旋法則示例詳解

    C++變量判定的螺旋法則示例詳解

    這篇文章主要給大家介紹了關(guān)于C++變量判定的螺旋法則,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • C++?OpenGL實(shí)現(xiàn)旋轉(zhuǎn)立方體的繪制

    C++?OpenGL實(shí)現(xiàn)旋轉(zhuǎn)立方體的繪制

    這篇文章主要主要為大家詳細(xì)介紹了如何利用C++和OpenGL實(shí)現(xiàn)旋轉(zhuǎn)立方體的繪制,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起動(dòng)手嘗試一下
    2022-07-07
  • c++中的string常用函數(shù)用法總結(jié)

    c++中的string常用函數(shù)用法總結(jié)

    以下是對(duì)c++中的string常用函數(shù)的用法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-09-09

最新評(píng)論