- 順序容器
| vector | 尾部之外的位置插入或刪除元素可能很慢 |
|---|---|
| deque | 頭尾位置插入、刪除速度很快 |
| list | 任何位置插入、刪除速度很快 |
| forward_list | 只支持單向順序訪問,任何位置插入、刪除都很快。 |
| array | 固定大小數(shù)組。不能添加刪除元素 |
| string | 隨機(jī)訪問快、尾部插入刪除很快。 |
- 容器操作
| 類型別名 | |
|---|---|
| iterator | 此容器類型的迭代器類型 |
| const_iterator | 讀取元素,不能修改元素的迭代器類型 |
| size_type | 無符號(hào)類型,保存此容器類型的最大可能容器的大小 |
| difference_type | 帶符號(hào)整數(shù)類型,兩個(gè)迭代器之間的距離 |
| value_type | 元素類型 |
| reference | 元素的左值類型;與value_type&含義相同 |
| const_reference | 元素的const左值類型(vonst vlue_type&) |
| 構(gòu)造函數(shù) | |
| C c; | 默認(rèn)構(gòu)造函數(shù),構(gòu)造空容器 |
| C c1(c2); | 構(gòu)造c2的拷貝到c1 |
| C c(b,e); | 構(gòu)造c,將接待器b和e范圍的元素拷貝到c(不支持array) |
| C c{a, b, c,...} | 列表初始化c |
| 賦值與swap | |
| C1 = c2 | |
| C1 = {a, b, c,...} | |
| a.swap(b);swap(a,b) | 交換a與b的元素 |
| 大小 | |
| c.size() | c中元素的數(shù)目(不支持forward_list) |
| c.max_size() | c可保存的最大元素?cái)?shù)目 |
| c.empty() | |
| 添加或刪除元素 | 在不同容器中,操作的接口不同 |
| c.insert(args) | 將args中的元素拷貝到c |
| c.emplace(inits) | 使用inits構(gòu)造c中的一個(gè)元素 |
| c.erase(args) | 刪除args指定的元素 |
| c.clear() | 刪除c中的所有元素,返回void |
| 關(guān)系運(yùn)算符 | 所有容器都支持:如==、!= |
| 獲取迭代器 | |
| c.cbegin(),c.cend() | 返回const_iterator |
| reverse_iterator | 逆序?qū)ぶ返牡?/td> |
容器定義和初始化
C seq(n); // seq包含n個(gè)元素,都被值初始化
C seq(n, t); // seq包含n個(gè)值為t的元素
list<string> authors = {"Milton", "Austen"}; //列表初始化
- notes: 1. 將一個(gè)容器初始化為另一個(gè)容器的拷貝時(shí),兩個(gè)容器的容器類型和元素類型都必須相同。
- 順序容器的構(gòu)造函數(shù)才接受大小參數(shù),關(guān)聯(lián)容器并不支持。
- 標(biāo)準(zhǔn)庫
array
使用array必須指定元素類型和大?。?/li>
array<int, 42> // 類型為:保存42個(gè)int的數(shù)組
array<int>:: size_type j; //錯(cuò)誤
不能對(duì)內(nèi)置數(shù)組類型進(jìn)行拷貝,但是array類型是可以的:
array<int ,10> digits = {0,1,2,3,4,5,6,7,8,9};
array<int, 10> copy = digits; // right
容器賦值運(yùn)算
賦值和swap
array<int, 10> a1 = {...};
array<int 10> a2 = {0}; //所有元素均為 0
a2 = {0}; //錯(cuò)誤,不能將一個(gè)花括號(hào)列表賦予數(shù)組
// 通常swap比從c2向c1拷貝元素要快
swap(c1,c2);
c1.swap(c2);
seq.assign(b, e); // 將seq中的元素替換為迭代器b和e所表示的范圍的元素,迭代器b、e不能指向seq中的元素
seq.assign(il); // 將seq中的元素替換為初始化列表il中的元素
seq.assign(n,t); // 將seq中的元素替換為n個(gè)值為t的元素
警告:賦值相關(guān)運(yùn)算會(huì)導(dǎo)致指向左邊容器內(nèi)部的迭代器、引用和指針失效。而swap操作將容器內(nèi)容交換不會(huì)導(dǎo)致指向容器的迭代器、引用和指針失效(array和string除外)。
順序容器的
assign
允許我們從一個(gè)不同但相容的類型賦值,或者從容器的一個(gè)子序列賦值。assign操作用參數(shù)所指定的元素(的拷貝)替換左邊容器中的所有元素。
list<string> names;
vector<const char*> oldstyle;
names = oldstyle; //錯(cuò)誤,容器類型不匹配
names.assign(oldstyle.cbegin(), oldstyle.cend()); //正確 可以將const char* 轉(zhuǎn)換為string
向順序容器添加元素
| c.push_back(t) , c.emplace_back(args) | c的尾部創(chuàng)建一個(gè)值為t或由args創(chuàng)建的元素。 |
|---|---|
| c.insert(p,t) , c.emplace(p,args) | 在迭代器p指向的元素之前創(chuàng)建一個(gè)值為p或由args創(chuàng)建的元素。 |
| c.insert(p, n , t) | 在迭代器p指向的元素之前插入n個(gè)值為t的元素。返回新添加的第一個(gè)元素的迭代器,若n為0,返回p |
| c.insert(p, b, e) | 將迭代器b、e指定的范圍內(nèi)的元素插入到迭代器p指向的元素之前。b、e不能指向c中的元素。 返回新添加的第一個(gè)元素的迭代器,若n為0,返回p |
| c.insert(p , il) | il是一個(gè)花括號(hào)保衛(wèi)的元素值列表,將這些值插入到p指向的元素之前。 返回新添加的第一個(gè)元素的迭代器,若n為0,返回p |
- insert的返回值
下面的例子,iter每次都指向新加入元素的位置:
list<string> lst;
auto iter = lst.begin();
while(cin>>word)
iter = lst.insert(iter, word); //等價(jià)于調(diào)用 push_front
- 使用
emplace操作
假設(shè)c里保存的是Sales_data成員:
c.emplace_back("970", 25, 15.99);
c.push_back("970", 25, 15.99); //錯(cuò)誤,沒有接受三個(gè)參數(shù)的push_back
c.push_back(Sales_data("970", 25, 15.99));
在調(diào)用emplace_back時(shí),會(huì)在容器管理的內(nèi)存空間中直接創(chuàng)建對(duì)象,而調(diào)用push_back則會(huì)創(chuàng)建一個(gè)局部臨時(shí)對(duì)象,并壓入容器中。
在順序容器匯總訪問元素
- 容器中沒有元素,訪問操作是未定義的。
- 包括
array在內(nèi)每個(gè)順序容器都有一個(gè)front成員函數(shù),除去forward_list之外的所有順序容器都有back成員函數(shù)。
vector<int> c={1,2,3,4,5,6};
if (!c.empty()){
// val和val2是c中第一個(gè)元素值的拷貝
auto val = *c.begin(), val2 = c.front();
// val3和val4是c中最后一個(gè)元素值的拷貝
auto last =c.end();
auto val3 =*(--last); // 不能遞減forward_list迭代器
auto val4 = c.back();
cout << val << " " << endl;
cout << val2 << " " << endl;
cout << val3 << " " << endl;
cout << val4 << " " << endl;
}
- 訪問成員函數(shù)返回的是引用:
front、back、at、下標(biāo)都是返回引用,如果容器是一個(gè)const對(duì)象,返回值是const的引用。
vector<int> c={1,2,3,4,5,6};
if (!c.empty()){
c.front() = 42;
auto &v = c.back(); // v是c.back()的一個(gè)引用
v = 1024;
cout << c.back() << endl;
auto v2 = c.back(); // v2不是一個(gè)引用,它是c.back()的一個(gè)拷貝
v2 = 0;
cout <<c.back();
}
1024
1024
- 下標(biāo)操作和安全的隨機(jī)訪問:
at在下標(biāo)越界的情況下,會(huì)拋出一個(gè)out_of_range的異常。
vector<string> svec;
cout << svec[0]; // 運(yùn)行時(shí)錯(cuò)誤
cout << svec.at(0); //拋出一個(gè)異常
順序容器的刪除操作
-
注意:刪除
deque中除首尾位置之外的任何元素都會(huì)是所有迭代器、引用、指針失效。指向vector、string中刪除點(diǎn)之后的迭代器、引用、指針失效。
| c.pop_back() | 刪除c中的尾元素。c為空,函數(shù)行為未定義。函數(shù)返回void |
|---|---|
| c.pop_front() | 刪除c中的首元素。c為空,函數(shù)行為未定義。函數(shù)返回void |
| c.erase(p) | 刪除迭代器p指定的元素,返回一個(gè)指向被刪除元素之后元素的迭代器,若p是尾后迭代器,則函數(shù)行為未定義 |
| c.erase(b, e) | 將迭代器b、e指定的范圍內(nèi)的元素刪除。若e是尾后迭代器,則函數(shù)返回尾后迭代器 |
| c.clear() | 刪除所有元素,返回void |
改變?nèi)萜鞯拇笮?/h4>
resize增大或縮小容器,array不支持。如果當(dāng)前大小大于所要求的大小,容器后部的元素被刪除;如果當(dāng)前大小小于新大小,新元素會(huì)添加:
list<int> ilist(10, 42); // 10個(gè)int:每個(gè)值為42
ilist.resize(15); // 將5個(gè)值為0的元素添加到ilist尾部
ilist.resize(25, -1); // 將10個(gè)值為-1的元素添加到ilist末尾
ilist.resize(5); // 從ilist末尾刪除20個(gè)元素