亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

淺析C++標準庫元組(tuple)源碼

2020-01-26 14:59:51
字體:
來源:轉載
供稿:網友

一、什么是元組

元組不是什么新鮮東西,在數學、python語言還有我們今天要說的C++都有元組。

簡單地說,元組就是一組東西,例如,在講代數拓撲的時候,經常把拓撲空間X和其中一點x作為一個偶對(X, x),這其實就是個元組,點的坐標也可以看成一個元組。C++中的元組(tuple)是這個樣子的:

std::tuple<int, std::string> tu{ 2,"12iop" };

一個tuple可以包含不同類型的成員,例如上面的tu包含一個int和一個字符串。

二、用法

在考察源碼之前,我們必須先知道它的用法。

要想使用tuple,要包含頭文件<tuple>:

#include <tuple>

tuple實際上是一個有可變參數的類模板,使用的時候,傳入若干個參數將其特化。

struct Point{ int x; int y;}; void main(){ std::tuple<int, std::string> t1{ 1,"qwer" }; // 一個由int和字符串組成的tuple constexpr std::tuple<int, void*> t2{ 1,nullptr }; // 一個由int和void*組成的tuple std::tuple<int, Point> t3{ 1,{20,89} }; // 一個由int和Point結構體組成的tuple std::tuple<int, char, std::string> t4{ 1,'t',"qwer" }; // 一個由int、char、字符串組成的tuple}

上面的代碼中,我用constexpr修飾了t2,這是完全正確的,std::tuple的構造函數是constexpr的。

獲取tuple中的值,用std::get。這不是函數,而是函數模板,我們需要傳入size_t類型的變量將其特化,或者傳入一個類型,告訴它我們需要取出元組中的哪個類型的成員。

struct Point{ int x; int y;}; void main(){ std::tuple<int, std::string> t1{ 1,"qwer" }; constexpr std::tuple<int, void*> t2{ 10,nullptr }; std::tuple<int, Point> t3{ 1,{20,89} }; std::tuple<int, char, std::string> t4{ 1,'t',"qwer" };  std::cout << std::get<0>(t1) << std::endl; // 1  constexpr int n2 = std::get<0>(t2); std::cout << n2 << std::endl; // 10  auto s = std::get<char>(t4); std::cout << s << std::endl; // t}

std::get也是constexpr的,所以n2也是一個編譯時的常量。

我們通過get<char>的方式得到了s,它是char類型的變量。std::get<T>可以從tuple中獲取到第一個類型為T的成員。

tuple也可以用【==】和【!=】比較是否相等:

std::tuple<int, std::string> t5{ 1,"qwer" }; if (t1 == t5){ std::cout << "==" << std::endl;}

介紹tuple的用法不是本文的主要內容,故到此為止。有興趣的同學可以自行查閱資料。

接下來,是時候考察一看源碼了。

三、源碼分析

tuple是個可變參數的類模板:

template<typename... _Types>class tuple;

這是對類模板的聲明。

接下來,實現參數個數為零的空tuple。

3.1 tuple<>

struct allocator_arg_t{}; template<>class tuple<>{public: typedef tuple<> _Myt;  constexpr tuple() noexcept {}  template<typename _Alloc> tuple(allocator_arg_t, const _Alloc&) noexcept {}  constexpr tuple(const tuple&) noexcept {}  template<class _Alloc> tuple(allocator_arg_t, const _Alloc&, const _Myt&) noexcept {}  void swap(_Myt&) noexcept {}  constexpr bool _Equals(const _Myt&) const noexcept { return true; }  constexpr bool _Less(const _Myt&) const noexcept { return false; }};

allocator_arg_t是個空的結構體,暫時不管它。_Myt就是tuple<>自己,這樣寫起來方便一些。

tuple<>定義了空的構造函數和拷貝構造函數(空tuple沒什么可做的)。

成員函數swap用于與另一個tuple<>交換內容,因為沒什么可交換的,函數體當然是空的。

_Equals用來判斷兩個tuple<>是否相等,它返回true,這是顯然的(所有的tuple<>都是一個樣子)。

_Less從函數名看,是為了比較大小,但如果遇到沒有重載<的類型呢?暫時不管它。

有了空tuple的定義,就可以定義非空的tuple。

3.2 非空的tuple

template<class _This,class... _Rest>class tuple<_This, _Rest...> : private tuple<_Rest...>{ // 內容}

n(>0)個元素的tuple私有繼承了n-1個元素的tuple。顯然這是一種遞歸定義,最終會遞歸到tuple<>,而tuple<>是已經定義好了得。

例如,tuple<int, char, short>私有繼承了tuple<char, short>,而tuple<char, short>又私有繼承了tuple<short>,tuple<short>私有繼承了tuple<>。由于私有繼承可以實現“has-a”功能,所以,這樣的方式可以將不同類型的對象組合在一起。如下圖:

那么,tuple是如何存儲其中的元素呢?

template<class _This,class... _Rest>class tuple<_This, _Rest...> : private tuple<_Rest...>{ // recursive tuple definitionpublic: typedef _This _This_type; typedef tuple<_This, _Rest...> _Myt; typedef tuple<_Rest...> _Mybase; static const size_t _Mysize = 1 + sizeof...(_Rest);  _Tuple_val<_This> _Myfirst; // 存儲的元素}

原來,它有個成員叫_Myfirst,它就是用來存儲_This類型的變量的。你會看到_Myfirst的類型不是_This而是_Tuple_val<_This>,其實,_Tuple_val又是一個類模板,它的代碼這里就不展開了,簡而言之,它的作用是存儲一個tuple中的變量。_Myfirst._Val才是真正的元素。

這個tuple只存儲一個元素,類型為_Rest...的其他元素存在基類_MyBase即tuple<_Rest...>中。我們仍然以tuple<int, char, short>為例,tuple<int, char, short>存儲了一個int,有基類tuple<char, short>;而tuple<char, short>存儲了一個char,有基類tuple<short>;tuple<short>存儲了一個short,有基類tuple<>;tuple沒有基類也不存儲任何元素。

3.3 構造函數

tuple的構造函數沒什么可說的,就是初始化_Myfirst和_MyBase,當然,_MyBase也要進行么一個過程,直到tuple<>。

 constexpr tuple(): _Mybase(), _Myfirst() {}  constexpr explicit tuple(const _This& _This_arg, const _Rest&... _Rest_arg) : _Mybase(_Rest_arg...), _Myfirst(_This_arg) {}  tuple(const _Myt&) = default; tuple(_Myt&&) = default;

它還提供了默認拷貝構造函數和移動構造函數(移動語義是C++11中新增的特性,請自行查閱資料)。其實,它還有很多構造函數,寫起來挺熱鬧,無非就是用不同的方式為它賦初值,故省略。

3.4 部分成員函數

tuple重載了賦值符號(=),這樣,tuple之間是可以賦值的

 template<class... _Other> _Myt& operator=(const tuple<_Other...>& _Right) { // assign by copying same size tuple _Myfirst._Val = _Right._Myfirst._Val; _Get_rest() = _Right._Get_rest(); return (*this); }

賦值符號返回左邊的引用,這種行為和C++的內置類型是一致的。_Get_rest是tuple的成員函數,作用是把除了_Myfirst之外的那些元素拿出來。

接下來是成員函數_Equals,

template<class... _Other>constexpr bool _Equals(const tuple<_Other...>& _Right) const{ static_assert(_Mysize == sizeof...(_Other), "comparing tuple to object with different size"); return (_Myfirst._Val == _Right._Myfirst._Val && _Mybase::_Equals(_Right._Get_rest()));}

其中進行了靜態斷言,如果兩個tuple的元素個數不相同,會引發一個編譯時的錯誤。如果對應的類型不能用==進行比較,在模板特化時也會引發編譯期的錯誤,例如,tuple<std::string, int>不能和tuple<int, char>比較,因為std::string和int是不能用==進行比較的。

前面提到的_Get_rest在這里:

_Mybase& _Get_rest() noexcept{ return (*this);} constexpr const _Mybase& _Get_rest() const noexcept{ return (*this);}

它返回對基類的引用。*this的類型雖然是_Myt,但根據C++語法(可以把派生類的引用賦給對基類的引用),所以這樣做是沒問題的。

以上就是C++標準庫元組(tuple)源碼淺析的全部內容,希望對大家的學習有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩免费网站| 欧美性猛交xxxx富婆| 自拍偷拍亚洲精品| 91深夜福利视频| 久久全国免费视频| 欧美高清视频一区二区| 亚洲热线99精品视频| 亚洲第一视频在线观看| 国产日韩欧美电影在线观看| 国产精品99久久久久久久久| 国产精品欧美日韩| 久久色免费在线视频| 日韩欧美高清在线视频| 日韩中文字幕在线播放| 成人国内精品久久久久一区| 亚洲老板91色精品久久| 欧美在线观看网站| 国产99视频在线观看| 亚洲午夜小视频| 国产在线视频欧美| 国产成人精品av在线| 日韩成人激情在线| 一区二区亚洲欧洲国产日韩| 久久视频在线直播| 激情成人中文字幕| 日本免费一区二区三区视频观看| 亚洲午夜未满十八勿入免费观看全集| 92国产精品视频| 日韩在线视频播放| 亚洲小视频在线观看| 91久久国产综合久久91精品网站| 亚洲色图25p| 国产精品免费一区豆花| 久久夜精品va视频免费观看| 欧美精品在线视频观看| 国产精品人成电影在线观看| 在线色欧美三级视频| 欧美激情视频一区| 久久频这里精品99香蕉| 美女999久久久精品视频| 精品福利一区二区| 亚洲精品日韩av| 搡老女人一区二区三区视频tv| 亚洲专区在线视频| 久久精品国产综合| 亚洲欧洲在线免费| 亚洲日本中文字幕| 欧美国产第二页| 欧美理论电影在线观看| 国产福利视频一区二区| 精品国产福利在线| 色综合五月天导航| 狠狠色香婷婷久久亚洲精品| 中文字幕久久亚洲| 久久免费视频在线观看| 久久免费视频这里只有精品| 在线精品视频视频中文字幕| 色偷偷亚洲男人天堂| 欧美一二三视频| 欧美激情亚洲视频| 国外成人免费在线播放| 国产精品视频男人的天堂| 97人人模人人爽人人喊中文字| 成人国产精品一区二区| 成人免费视频97| 亚洲老头老太hd| 久久影视电视剧凤归四时歌| 久久精品视频va| 日韩女优人人人人射在线视频| 在线观看亚洲视频| 欧美激情第1页| 国产精品久久久久久久久久新婚| 日韩欧美精品网站| 欧美精品精品精品精品免费| 日韩av免费在线| 51精品国产黑色丝袜高跟鞋| 91影院在线免费观看视频| 国产精品激情av电影在线观看| 国产成人高潮免费观看精品| 中文字幕日韩精品有码视频| 欧美日韩国产麻豆| 国产精品国产自产拍高清av水多| 久久久久在线观看| 欧美日韩国产精品一区| 亚洲精品色婷婷福利天堂| 亚洲激情自拍图| 亚洲区免费影片| 国产精品吊钟奶在线| 欧美一级在线亚洲天堂| 亚洲免费福利视频| 欧美精品成人在线| 日韩中文在线观看| 午夜欧美大片免费观看| 久久99精品久久久久久噜噜| 国产欧洲精品视频| 亚洲免费电影在线观看| 亚洲图片欧美日产| 日韩福利伦理影院免费| 亚洲永久免费观看| 中日韩美女免费视频网址在线观看| 久久久精品欧美| 亚洲国内高清视频| 欧美中在线观看| 亚洲精品电影网在线观看| 91理论片午午论夜理片久久| 国产亚洲欧美aaaa| 午夜精品99久久免费| 亚洲天堂精品在线| 2024亚洲男人天堂| 中文字幕亚洲欧美在线| 欧美日韩一区二区三区| www.久久色.com| 成人福利免费观看| 97色在线视频观看| 日韩美女免费线视频| 91在线色戒在线| 精品视频一区在线视频| 国产精品美女视频网站| 欧美在线观看视频| 777国产偷窥盗摄精品视频| 国产精品999| 欧美黄色三级网站| 国产精品久久久久久久久久小说| 久久精品国产亚洲精品2020| 日韩大片在线观看视频| 日韩av资源在线播放| 亚洲第一精品电影| 亚洲va码欧洲m码| 日韩成人高清在线| 日韩精品高清视频| 国产极品精品在线观看| 热re91久久精品国99热蜜臀| 在线视频精品一| 国产精品成av人在线视午夜片| 欧美激情一区二区三区高清视频| 国产精品露脸av在线| 日韩精品免费在线| 亚洲a中文字幕| 久久影视电视剧免费网站清宫辞电视| 日本成人黄色片| 91av成人在线| 97精品久久久中文字幕免费| 亚洲第一中文字幕| 成人免费视频97| 自拍偷拍免费精品| 国产精品电影在线观看| 久久久久这里只有精品| 国模极品一区二区三区| 日韩中文字幕在线免费观看| 麻豆一区二区在线观看| 永久免费毛片在线播放不卡| 97香蕉超级碰碰久久免费软件| 秋霞成人午夜鲁丝一区二区三区| 一区三区二区视频| 91a在线视频| 俺也去精品视频在线观看| 日韩欧美精品中文字幕| 国产综合香蕉五月婷在线| 久久久国产精品一区| 欧美自拍视频在线观看| 91在线观看免费观看| 国产精品三级在线| 日韩电影在线观看永久视频免费网站| 国内精品久久久久久影视8|