一、C++ STL各容器有一些共通的能力
其中三個最核心的能力是:
(1)所有容器提供的是“value語意”而不是“reference語意”。
容器進行元素的安插操作時,內部實施的是拷貝操作,存放的是元素的副本。因此容器的每一個元素必須能被拷貝。
如果打算存放的對象不具備public 拷貝構造函數或者你要得不是對象的副本,那麼容器元素只能是指針。
(2)所有元素形成一個次序。
我們可以以相同順序一次或者多次遍歷每個元素。每個容器都提供可返回迭代器的函數,運用這些迭代器可以遍歷元素。
(3)一般來說,各項操作並非絕對安全。
調用者必須確保傳給操作函數的參數符合需求。違反需求的會導致未定義的行為。而且STL通常不會自己跑出異常。
二、容器的共通操作
下表列出容器的共通操作函數:
(1)初始化
每個容器類別都提供了一個默認構造函數、一個拷貝構造函數和一個析構函數。
以另一個容器的元素為初值,進行初始化:
list<int> intList;
vector<float> floatVec(intList.begin(),intList.end());
以一個數組的元素為初值進行初始化:
int array[] = {1,2,3,4,5};
set<int> intSet(array,array + sizeof(array) / sizeof(array[0]));
從標准輸入獲取元素進行初始化:
deque<int> c((istream_iterator<int>(cin)),
(istream_iterator<int>()));
注意:不能遺漏了初始化參數的那對多余的括號:
不能是這樣的:
deque<int> c(istream_iterator<int>(cin),
istream_iterator<int>());
否則,表達式被認為是一個函數c的聲明。它的一個參數的型別是istream_iterator<int>,參數名是cin。第二個參數無名,型別是istream_iterator<int>。函數的返回值型別是istream_iterator<int>。
但是,我們通過加上一對括號,就可以使參數istream_iterator<int>(cin)不再符合聲明語法。
因為C++標准中的語法不接受這樣的函數聲明形式:
T name((U), (V));
(2)與大小相關的操作函數
1、size()
返回當前元素的數量
2、empty()
等價於size() == 0.但是其效率可能會高些。所以應該盡量使用empty()。
3、max_size()
返回容器所能容納的最大元素數量。其值會因實作版本不同而不同。
(3)比較
包括常用的==,!=,<,<=,>,>=。
注意:比較操作的兩端即兩個容器必須屬於同一型別。如果容器的所有元素依次序相等,則兩個容器相等。采用operator==檢查元素是否相等。采用字典式書序比較原則來判斷某個容器是否小於另一個容器。
(4)賦值和swap交換
當對容器賦值元素時,源容器的所有元素被拷貝到目標容器內,後者的所有元素完全被移除。所以,賦值操作代價較高。
如果兩個容器的型別相同,而且拷貝後源容器不在使用,可以使用swap進行優化。它的性能要優異很多。事實上它只交換某些內部指針,所以時間復雜度是常數,而賦值操作的復雜度是線性的。
摘自 江南煙雨