從C開始,c++發展過來也一樣,在標準庫中一般不支持複雜的數據結構。比如多維的數組,多鍵值的KV,更不用說複雜的一批的樹了。其實也很好理解,c/c++作為一個底層支持語言,追求的是高效和多平臺支持,這就導致無法在複雜的數據結構中對整個數據結構進行極致優化,特別是針對於特定的平臺的極致優化。這也是很多大牛自己手擼一些(如跳表等)的數據結構。
用形象的話來說,STL庫就是一些「短小精悍」的函數和類組成,所以就不會有特別複雜的數據結構表現出來,其實在底層還是有一些複雜數據結構(紅黑樹),比如map的底層實現。
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中實現的東西,多少都是很多大牛們審過的,拿出來搞一搞事情,也可以接受。還是那句話,要善於學習,不要固步自封,這才是進步的動力和源泉。