c++中的pair和tuple

2021-12-29 太平洋工作室

一、c++中的複雜數據結構

從C開始,c++發展過來也一樣,在標準庫中一般不支持複雜的數據結構。比如多維的數組,多鍵值的KV,更不用說複雜的一批的樹了。其實也很好理解,c/c++作為一個底層支持語言,追求的是高效和多平臺支持,這就導致無法在複雜的數據結構中對整個數據結構進行極致優化,特別是針對於特定的平臺的極致優化。這也是很多大牛自己手擼一些(如跳表等)的數據結構。
用形象的話來說,STL庫就是一些「短小精悍」的函數和類組成,所以就不會有特別複雜的數據結構表現出來,其實在底層還是有一些複雜數據結構(紅黑樹),比如map的底層實現。

二、pair和tuple

pair和tuple都是用來進行複雜數據封裝的數據結構,前者類似於KV型資料庫,一對一對兒的。後者可以認為是Pair的擴充,可以支持更多的value在一個元素內,早期的標準是支持十個以內,而在c++11以後,可以支持更多的value。其實對於c/c++來說,可以互相封裝,這樣就會產生更大的組合結構,比如可以把兩個tuple組合到pair中。
看一下STL對它們的定義:

//Defined in header <utility>
template<
    class T1,
    class T2
> struct pair;

//Defined in header <tuple>
template< class... Types >
class tuple;

對於pair除了可以使用構造函數,STL提供了一個便捷的方式std::make_pair<>來創建,一般也推薦這麼操作。pair提供了交換、比較等常見的操作,使用越來還是比較方便的。對tuple來說,STL稱它為不定長值組,它比pair要複雜,但可以轉到std::tie。這個std::tie是一個tuple 的左值引用,它比較有意思。tuple也提供了一個std::make_tuple<>來創建,有一就有二嘛。同時它還提供一個tuple_cat()函數,看名字都知道可以把多個tuple連接在一起,這個在特定的場合下很有用。
同樣,在c++11以後可以使用initializer list(初始化列表)來實現整體的賦值構造。pair和tuple可以通過相關的構造函數來實現轉換,但看上去使用仍然不是很靈活。

三、例程

先看一下pair的例程:

#include <iostream>
#include <utility>
#include <functional>

int main()
{
    int n = 1;
    int a[5] = {1, 2, 3, 4, 5};

    // build a pair from two ints
    auto p1 = std::make_pair(n, a[1]);
    std::cout << "The value of p1 is "
              << "(" << p1.first << ", " << p1.second << ")\n";

    // build a pair from a reference to int and an array (decayed to pointer)
    auto p2 = std::make_pair(std::ref(n), a);
    n = 7;
    std::cout << "The value of p2 is "
              << "(" << p2.first << ", " << *(p2.second + 2) << ")\n";
}

運行結果:

The value of p1 is (1, 2)
The value of p2 is (7, 3)

再看看tuple:

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

std::tuple<int, int> f() // this function returns multiple values
{
    int x = 5;
    return std::make_tuple(x, 7); // return {x,7}; in C++17
}

int main()
{
    // heterogeneous tuple construction
    //std::tuple<int, int>{1, -1}; // initializer list
    int n = 1;
    auto t = std::make_tuple(10, "Test", 3.14, std::ref(n), n);
    n = 7;
    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";

    // function returning multiple values
    int a, b;
    std::tie(a, b) = f();
    std::cout << a << " " << b << "\n";
}

運行結果:

The value of t is (10, Test, 3.14, 7, 1)
5 7

四、總結

這兩個數據結構是挺簡單的一個應用,傳統的程式設計師一般會自己封裝一些數據結構來實現類似的功能。不過STL中實現的東西,多少都是很多大牛們審過的,拿出來搞一搞事情,也可以接受。還是那句話,要善於學習,不要固步自封,這才是進步的動力和源泉。

相關焦點

  • C++(STL):02---tuple容器
    三、定義和初始化tuplestd::tuple<size_t, size_t, size_t> threeD; //使用默認構造函數std::tuple&get<0>(t) = "hello"; //s變為helloTuple和初值列template<typename...
  • Redhat2019CTF上利用 honggfuzz 和 QEMU 插樁完成題目的WriteUp
    /include/c++/7.4.0/bits/basic_string.h:440 #11 std::pair::pair(std::tuple&, std::tuple<>&, std::_Index_tuple, std::_Index_tuple<>) (this=0x55555569ec30, __tuple1=..., __tuple2
  • C++ protected 繼承和 private 繼承是不是沒用的廢物?
    實踐是檢驗真理的唯一標準,現實世界中的這些項目情況是否能說明protected繼承和private繼承是沒用的廢物?是只會出現在語法理論和教科書中的垃圾嗎?pair:和 varient 還是挺給我面子的:tuple:
  • c++11新特性,所有知識點都在這了!
    cont int &i = 1;int a = 2;decltype(i) b = 2; 關於auto和decltype的詳細介紹請看:一文吃透C++11中auto和decltype知識點c++,說它特別難,可能有一部分就是因為c++的內存管理吧,不像java那樣有虛擬機動態的管理內存,在程序運行過程中可能就會出現內存洩漏,然而這種問題其實都可以通過c++11引入的智能指針來解決,相反我還認為這種內存管理還是c++語言的優勢,因為盡在掌握。
  • 跟我學C++中級篇——STL中的字符串
    一、字符串在傳統的C/C++語言中,對字符串的處理比較麻煩,基本都是用char*來操作,而指針又往往是一個初學者的噩夢。STL為了解決這個問題,提供了std::string這個數據結構,其實它就是一個類,不過其提供了常見的對字符串的操作符的重載,實現在實際工程中經常遇到的字符串的長度計算,拼接和裁剪以及和C類型字符串的轉換。它不算是STL的容器,它只是一個類。
  • C++14新特性的所有知識點全在這兒啦!
    函數可以使用遞歸,在C++14中可以使用局部變量和循環constexpr int factorial(int n) { return n <= 1 ?::shared_lock來實現讀寫鎖,保證多個線程可以同時讀,但是寫線程必須獨立運行,寫操作不可以同時和讀操作一起進行。
  • Python的list和tuple
    list是一種有序的集合,可以隨時添加和刪除其中的元素。tuple另一種有序列表叫元組:tuple。tuple和list非常類似,但是tuple一旦初始化就不能修改,比如同樣是列出同學的名字:>>> classmates = ('Michael', 'Bob', 'Tracy')現在,classmates這個tuple不能變了,它也沒有append(),insert()這樣的方法。
  • C++ primer 練習題 1
    std::tuple<int, int, int> t1{10, 20, 30};auto t2 = std::make_tuple(10, 20, 30);練習17.2定義一個 tuple,保存一個 string、一個vector<string> 和一個 pair<string, int>。
  • python中namedtuple與OrderedDict 的使用
    今天來講解一下python中的 Namedtuple與OrderedDict 的使用。一、Namedtuple我們都知道,在python的數據結構裡,tuple(元組)表示的是不可變集合。那麼,nametuple就派上了用場:from collections import namedtuplePoint = namedtuple('Point', ['x', 'y'])p = Point(1, 2)p.xp.y如果用坐標和半徑表示一個圓,也可以用nametuple來定義:#namedtuple('名稱', [屬性list]):Circle =
  • 好冷的Python–tuple和逗號的糾纏
    在 《Python混合編程–C語言接口ctypes(1)》中講到封裝C函數時的argstype ,以及在《Python進階–多線程
  • python3.6中數據類型之list和tuple的比較
    list使用中括號,有序,可修改其中的數值tuple使用小括號,有序,不可修改其中的數值我們分別定義一個list,一個tuple.list[2]),從右向左數第2個就是print(list[-2])>>> print(list[2])first milk_tea of autumn>>> print(list[-2])first milk_tea of autumn>>>我們的list[2]和list
  • three pair of shoes中的pair要改為pairs嗎?
    有次和同事聊天,他說很多學英語的人不知道pair的複數形式有兩種,一個是pairs,一個是pair,很多人見到three pair of shoes
  • 數據容器 tuple
    ,[]中給定索引值index即可訪問tuple中的元素。Python 中的索引分為正索引和負索引。 正索引從 0 開始進行編號, 表示數據集合中的第一個元素。 負索引從-1 開始編號, 表示tuple中倒數第一個元素。正負索引值必須在有效的範圍之內, 否則會拋出越界訪問的錯誤信息。
  • 2.1 Python基礎知識(List和Tuple)
    list是一種有序的集合,可以隨時添加和刪除其中的元素。構造list非常簡單,按照上面的代碼,直接用 [ ] 把list的所有元素都括起來,就是一個list對象。由於Python是動態語言,所以list中包含的元素並不要求都必須是同一種數據類型。
  • Python的List與Tuple
    和字符串一樣,列表同樣可以被索引和截取,列表被截取後返回一個包含所需元素的新列表。列表截取的語法格式如下:變量[頭下標:尾下標]索引值以 0 為開始值,-1 為從末尾的開始位置。加號(+)是列表連接運算符,星號(*)是重複操作。
  • Python中比元組更好用的namedtuple
    其他內置函數(all、any、max、min、list、tuple、enumerate、sorted等)◆ 最大的痛點是只能通過數字索引來取值◆ 當元組中元素非常大時,通過索引取值非常不方便定義命名元組類的三種方法以及rename和defaults參數:
  • 數據類型介紹——tuple、list和range對象
    根據官網(https://docs.python.org/3/library/stdtypes.html)描述,Python解釋器中主要的內置類型有數字、序列、映射、類、實例和異常(The following sections describe the standard types that are built into the interpreter.
  • 如何正確通過 C++ Primer 學習 C++?
    ,但是研究生讀的專業在計算機學院,要求所有研究生都要會編程。多用智能指針和容器,遠離segment fault. 第10章裡的泛型算法可以慢慢讀,讀完以後可以寫出高逼格的函數式風格C++。12.2節講了怎麼用new和delete分配空間,題主作為新手,知道這種寫法就行,寫程序時儘量用容器代替原始數組,尤其是代碼裡最好不要有delete。Part3是塊硬骨頭,標題就是Tools for Class Authors.
  • Python基礎篇——關於元組(tuple)和列表(list)區別
    一、前言在Python數據類型中有兩個對象:元組 tuple 和列表 list 。二者寫法和用法十分相似,有的同學就會去網上查找它們之間的區別,查到的無非以下幾種說法:list 是可變的,元組 tuple 是不可變的。由於 tuple 不可變,所以使用 tuple 可以使代碼更安全。等等 ...
  • Python中列表(list),元組(Tuple),字典(Dict)和集合(Set)的比較
    1.1 元素索引列表、元組的索引都是從起始位置0開始的,甚至可以採用負數,例如:>>> list[0]1>>> list[-1]5>>> list[:-1][1, 2, 3, 4]>>> tuple[-1]5>&