- 順序容器類(lèi)型
類(lèi)型 |
解釋 |
vector |
可變大小數(shù)組。支持快速隨機(jī)訪(fǎng)問(wèn)。在尾部之外的位置插入或刪除元素可能很慢 |
deque |
雙端隊(duì)列。支持快速隨機(jī)訪(fǎng)問(wèn)。在頭尾位置插入、刪除速度很快 |
list |
雙向鏈表。只支持雙向順序訪(fǎng)問(wèn)。在list中任何位置進(jìn)行插入、刪除操作速度都很快 |
forward_list |
單向鏈表。只支持單向順序訪(fǎng)問(wèn)。在鏈表任何位置進(jìn)行插入、刪除操作速度都很快 |
array |
固定大小數(shù)組。支持快速隨機(jī)訪(fǎng)問(wèn)。不能添加或刪除元素 |
string |
與vector相似的容器,但專(zhuān)門(mén)用于保存字符。隨機(jī)訪(fǎng)問(wèn)快。在尾部插入、刪除速度快。 |
string 和vector 將元素保存在連續(xù)的內(nèi)存空間中。由元素的下標(biāo)來(lái)計(jì)算其地址是非??焖俚模谥虚g位置添加或刪除元素就會(huì)非常耗時(shí)。list 和forward_list 兩個(gè)容器的設(shè)計(jì)目的是令容器任何位置的添加和刪除操作都很快速,作為代價(jià),這兩個(gè)容器不支持元素的隨機(jī)訪(fǎng)問(wèn),并且相比vector、deque、array,這兩個(gè)容器的額外內(nèi)存開(kāi)銷(xiāo)也很大。deque 支持快速的隨機(jī)訪(fǎng)問(wèn),在deque的兩端添加或刪除元素都是很快的,與list或forward_list添加刪除元素的速度相當(dāng)。array 對(duì)象的大小是固定的。因此,array不支持添加和刪除元素以及改變?nèi)萜鞔笮〉牟僮鳌?code>forward_list的設(shè)計(jì)目標(biāo)是達(dá)到與最好的手寫(xiě)的單向鏈表數(shù)據(jù)結(jié)構(gòu)相當(dāng)?shù)男阅堋R虼?,forward_list沒(méi)有size操作,因?yàn)楸4婊蛴?jì)算其大小就會(huì)比手寫(xiě)鏈表多出額外的開(kāi)銷(xiāo)。對(duì)其他容器而言,size保證是一個(gè)快速的常量時(shí)間的操作。
- 以下是一些選擇容器的基本原則:
- 除非你有很好的理由選擇其他容器,否則應(yīng)使用vector。
- 如果你的程序有很多小的元素,且空間的額外開(kāi)銷(xiāo)很重要,則不要使用list或forward_list。
- 如果程序要求隨機(jī)訪(fǎng)問(wèn)元素,應(yīng)使用vector或deque。
- 如果程序要求在容器的中間插入或刪除元素,應(yīng)使用list或forward_list。
- 如果程序需要在頭尾位置插入或刪除元素,但不會(huì)在中間位置進(jìn)行插入或刪除操作,則使用deque。
- 如果程序只有在讀取輸入時(shí)才需要在容器中間位置插入元素,隨后需要隨機(jī)訪(fǎng)問(wèn)元素,則
- 首先,確定是否真的需要在容器中間位置添加元素。當(dāng)處理輸入數(shù)據(jù)時(shí),通??梢院苋菀椎叵騰ector追加數(shù)據(jù),然后再調(diào)用標(biāo)準(zhǔn)庫(kù)的sort函數(shù)來(lái)重排容器中的元素,從而避免在中間位置添加元素。
- 如果必須在中間位置插入元素,考慮在輸入階段使用list,一旦輸入完成,將list中的內(nèi)容拷貝到一個(gè)vector中。
- 如果你不確定應(yīng)該使用哪種容器,那么可以在程序中只使用vector和list公共的操作:使用迭代器,不使用下標(biāo)操作,避免隨機(jī)訪(fǎng)問(wèn)。這樣,在必要時(shí)選擇使用vector或list都很方便。
- 容器類(lèi)型上的操作形成了一種層次:
- 某些操作是所有容器類(lèi)型都提供的。
- 另外一些操作僅針對(duì)順序容器、關(guān)聯(lián)容器或無(wú)序容器。
- 還有一些操作只適用于一小部分容器。
- 順序容器構(gòu)造函數(shù)的一個(gè)版本接受容器大小參數(shù),它使用了元素類(lèi)型的默認(rèn)構(gòu)造函數(shù)。但某些類(lèi)沒(méi)有默認(rèn)構(gòu)造函數(shù)。我們可以定義一個(gè)保存這種類(lèi)型對(duì)象的容器,但我們?cè)跇?gòu)造這種容器時(shí)不能只傳遞給它一個(gè)元素?cái)?shù)目參數(shù):
// 假定noDefault是一個(gè)沒(méi)有默認(rèn)構(gòu)造函數(shù)的類(lèi)型
vector<noDefault> v1(10, init); // 正確:提供了元素初始化器
vector<noDefault> v2(10); // 錯(cuò)誤:必須提供一個(gè)元素初始化器
- 容器操作:
類(lèi)型別名 |
解釋 |
iterator |
此容器類(lèi)型的迭代器類(lèi)型 |
const_iterator |
可以讀取元素,但不能修改元素的迭代器類(lèi)型 |
size_type |
無(wú)符號(hào)整數(shù)類(lèi)型,足夠保存此種容器類(lèi)型最大可能容器的大小 |
difference_type |
帶符號(hào)整數(shù)類(lèi)型,足夠保存兩個(gè)迭代器之間的距離 |
value_type |
元素類(lèi)型 |
reference |
元素的左值類(lèi)型;與value_type& 含義相同 |
const_reference |
元素的const左值類(lèi)型(即,const value_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指定的范圍內(nèi)的元素內(nèi)的元素拷貝到c |
C c{a,b,c...}; |
列表初始化c |
賦值與swap |
解釋 |
c1=c2 |
將c1中的元素替換為c2中元素 |
c1={a,b,c...} |
將c1中的元素替換為列表中元素 |
a.swap(b) |
交換a和b的元素 |
swap(a,b) |
與a.swap(b)等價(jià) |
大小 |
解釋 |
c.size() |
c中元素的數(shù)目 |
c.max_size() |
c可保存的最大元素?cái)?shù)目 |
c.empty() |
若c中儲(chǔ)存了元素,返回false,否則返回true |
添加、刪除元素 |
解釋 |
c.insert(args) |
將args中的元素拷貝進(jìn)c |
c.emplace(inits) |
使用inits構(gòu)造c中的一個(gè)元素 |
c.erase(args) |
刪除args指定的元素 |
c.clear() |
刪除c中的所有元素,返回void |
關(guān)系運(yùn)算符 |
解釋 |
==,!= |
所有容器都支持相等(不等)運(yùn)算符 |
<,<=,>,>= |
刪除c中的所有元素,返回void |
獲取迭代器 |
解釋 |
c.begin(),c.end() |
返回指向c的首元素和尾元素之后位置的迭代器 |
c.cbegin(),c.cend() |
返回const_iterator |
反向容器的額外成員(不支持forward_list) |
解釋 |
reverse_iterator |
按逆序?qū)ぶ吩氐牡?/td>
|
const_reverse_iterator |
不能修改元素的逆序迭代器 |
c.rbegin(),c.rend() |
返回指向c的尾元素和首元素之前位置的迭代器 |
c.crbegin(),c.crend() |
返回const_reverse_iterator |
-
forward_list迭代器不支持遞減運(yùn)算符(--)。
-
一個(gè)迭代器范圍由一對(duì)迭代器表示,兩個(gè)迭代器分別指向同一個(gè)容器中的元素或者是尾元素之后的位置。
-
迭代器范圍中的元素包含first所表示的元素以及從first開(kāi)始直至last(但不包含last)之間的所有元素。左閉合區(qū)間:[left, right)。
-
如果滿(mǎn)足如下條件,兩個(gè)迭代器begin和end構(gòu)成一個(gè)迭代器范圍:
- 它們指向同一個(gè)容器中的元素,或者是容器最后一個(gè)元素之后的位置,且
- 我們可以通過(guò)反復(fù)遞增begin來(lái)到達(dá)end。換句話(huà)說(shuō),end不在begin之前。
-
標(biāo)準(zhǔn)庫(kù)使用左閉合范圍是因?yàn)檫@種范圍有三種方便的性質(zhì)。假定begin和end構(gòu)成一個(gè)合法的迭代器范圍,則
- 如果begin與end相等,則范圍為空
- 如果begin與end不等,則范圍至少包含一個(gè)元素,且begin指向該范圍中的第一個(gè)元素
- 我們可以對(duì)begin遞增若干次,使得begin==end
-
這些性質(zhì)意味著我們可以用循環(huán)來(lái)處理一個(gè)元素范圍。
while (begin != end)
{
*begin = val; // 正確:范圍非空,因此begin指向一個(gè)元素
// 在while循環(huán)中,可以安全地解引用begin,因?yàn)閎egin必然指向一個(gè)元素。
++begin; // 移動(dòng)迭代器,獲取下一個(gè)元素
}
-
反向迭代器就是一種反向遍歷容器的迭代器,與正向迭代器相比,各種操作的含義也都發(fā)生了顛倒。例如,對(duì)一個(gè)反向迭代器執(zhí)行++操作,會(huì)得到上一個(gè)元素。
-
begin和end有多個(gè)版本:帶r的版本返回反向迭代器;以c開(kāi)頭的版本則返回const迭代器;不以c開(kāi)頭的函數(shù)都是被重載過(guò)的。一個(gè)是const成員,返回容器的const_iterator類(lèi)型;另一個(gè)是非常量成員,返回容器的iterator類(lèi)型。當(dāng)我們對(duì)一個(gè)非常量對(duì)象調(diào)用這些成員時(shí),得到的是返回iterator的版本。只有在對(duì)一個(gè)const對(duì)象調(diào)用這些函數(shù)時(shí),才會(huì)得到一個(gè)const版本。與const指針和引用類(lèi)似,可以將一個(gè)普通的iterator轉(zhuǎn)換為對(duì)應(yīng)的const_iterator,但反之不行。
-
當(dāng)auto與begin或end結(jié)合使用時(shí),獲得的迭代器類(lèi)型依賴(lài)于容器類(lèi)型,與我們想要如何使用迭代器毫不相干。但以c開(kāi)頭的版本還是可以獲得const_iterator的,而不管容器的類(lèi)型是什么。當(dāng)不需要寫(xiě)訪(fǎng)問(wèn)時(shí),應(yīng)該使用cbegin和cend。
-
容器定義和初始化
方法 |
解釋 |
C c; |
默認(rèn)構(gòu)造函數(shù)。如果c是一個(gè)array,則c中元素按默認(rèn)方式初始化;否則c為空 |
C c1(c2) |
c1初始化為c2的拷貝。c1和c2必須是相同類(lèi)型(即,它們必須是相同的容器類(lèi)型,且保存的是相同的元素類(lèi)型;對(duì)于array類(lèi)型,兩者還必須具有相同大?。?/td>
|
C c{a,b,c...}或C c={a,b,c...} |
c初始化為初始化列表中元素的拷貝。列表中元素的類(lèi)型必須與c的元素類(lèi)型相容。對(duì)于array類(lèi)型,列表中元素?cái)?shù)目必須等于或小于array的大小,任何遺漏的元素都進(jìn)行值初始化 |
C c(b,e) |
c初始化為迭代器b和e指定范圍中的元素的拷貝。范圍中元素的類(lèi)型必須與C的元素的類(lèi)型相容(array不適用) |
—— |
只有順序容器(不包括array)的構(gòu)造函數(shù)才能接受大小參數(shù) |
C seq(n) |
seq包含n個(gè)元素,這些元素進(jìn)行了值初始化;此構(gòu)造函數(shù)是explicit的。(string不適用) |
C seq(n,t) |
seq包含n個(gè)初始化為值t的元素 |
-
當(dāng)將一個(gè)容器初始化為另一個(gè)容器的拷貝時(shí),兩個(gè)容器的容器類(lèi)型和元素類(lèi)型都必須相同。但當(dāng)傳遞迭代器參數(shù)來(lái)拷貝一個(gè)范圍時(shí),就不要求容器類(lèi)型是相同的了。而且,新容器和原容器中的元素類(lèi)型也可以不同,只要能將要拷貝的元素轉(zhuǎn)換為要初始化的容器的元素類(lèi)型即可(構(gòu)造函數(shù)只是讀取范圍中的元素并進(jìn)行拷貝)。
// 每個(gè)容器有三個(gè)元素,用給定的初始化器進(jìn)行初始化
list<string> authors = {"Milton", "Shakespeare", "Austen"};
vector<const char*> articles = {"a", "an", "the"};
list<string> list2(authors); // 正確:類(lèi)型匹配
deque<string> authList(authors); // 錯(cuò)誤:容器類(lèi)型不匹配
vector<string> words(articles); // 錯(cuò)誤:容器類(lèi)型必須匹配
// 正確:可以將const char*元素轉(zhuǎn)換為string
forward_list<string> words(articles.begin(),articles.end());
-
如果元素類(lèi)型是內(nèi)置類(lèi)型或者是具有默認(rèn)構(gòu)造函數(shù)的類(lèi)類(lèi)型,可以只為構(gòu)造函數(shù)提供一個(gè)容器大小參數(shù)。如果元素類(lèi)型沒(méi)有默認(rèn)構(gòu)造函數(shù),除了大小參數(shù)外,還必須指定一個(gè)顯示的元素初始值。
#include <iostream>
#include <vector>
using namespace std;
class A
{
private:
vector<int> data;
public:
A(vector<int>::iterator beg, vector<int>::iterator end)
{
data.assign(beg, end);
}
void display()
{
for (auto i : data)
cout << i << " ";
cout << endl;
}
};
int main()
{
vector<int> iv{1, 2, 3};
vector<A> one(5, A(iv.begin(), iv.end()));
for (auto i : one)
i.display();
cout << endl;
return 0;
}
-
只有順序容器的構(gòu)造函數(shù)才接受大小參數(shù),關(guān)聯(lián)容器并不支持。
-
標(biāo)準(zhǔn)庫(kù)array的大小也是類(lèi)型的一部分。當(dāng)定義一個(gè)array時(shí),除了指定元素類(lèi)型,我們必須同時(shí)指定元素類(lèi)型和大小。
array<int, 42> // 類(lèi)型為:保存42個(gè)int的數(shù)組
array<string, 10> // 類(lèi)型為:保存10個(gè)string的數(shù)組
array<int, 10>::size_type i; // 數(shù)組類(lèi)型包括元素類(lèi)型和大小
array<int>::size_type j; // 錯(cuò)誤:array<int>不是一個(gè)類(lèi)型
-
一個(gè)默認(rèn)構(gòu)造的array是非空的:它包含了于其大小一樣多的元素。這些元素都被默認(rèn)初始化,就像一個(gè)內(nèi)置數(shù)組中的元素那樣。如果我們對(duì)array進(jìn)行列表初始化,初始值的數(shù)目必須等于或小于array的大小。如果初始值數(shù)目小于array的大小,則它們被用來(lái)初始化array中靠前的元素,所有剩余元素都會(huì)進(jìn)行值初始化。在這兩種情況下,如果元素類(lèi)型是一個(gè)類(lèi)類(lèi)型,那么該類(lèi)必須有一個(gè)默認(rèn)構(gòu)造函數(shù),以使值初始化能夠進(jìn)行。
array<int, 10> ia1; // 10個(gè)默認(rèn)初始化的int
array<int, 10> ia2 = {0,1,2,3,4,5,6,7,8,9}; // 列表初始化
array<int, 10> ia3 = {42}; // ia3[0]為42,剩余元素為0
int digs[10] = {0,1,2,3,4,5,6,7,8,9};
int cpy[10] = digs; // 錯(cuò)誤:內(nèi)置數(shù)組不支持拷貝或賦值
array<int, 10> digits = {0,1,2,3,4,5,6,7,8,9};
array<int, 10> copy = digits; // 正確:只要數(shù)組類(lèi)型匹配即合法
-
與其他容器一樣,array也要求初始值的類(lèi)型必須與要?jiǎng)?chuàng)建的容器類(lèi)型相同。此外,array還要求元素類(lèi)型和大小也都一樣,因?yàn)榇笮∈莂rray類(lèi)型的一部分。
-
與賦值相關(guān)的運(yùn)算符可用于所有容器。賦值運(yùn)算符將其左邊容器中的全部元素替換為右邊容器中元素的拷貝。如果兩個(gè)容器原來(lái)大小不同,賦值運(yùn)算后兩者的大小都與右邊容器的原大小相同。
c1 = c2; // 將c1的內(nèi)容替換為c2中元素的拷貝
c1 = {a,b,c}; // 賦值后,c1大小為3
-
與內(nèi)置數(shù)組不同,標(biāo)準(zhǔn)庫(kù)array類(lèi)型允許賦值。賦值號(hào)左右兩邊的運(yùn)算對(duì)象必須具有相同的類(lèi)型。由于右邊運(yùn)算對(duì)象的大小可能與左邊運(yùn)算對(duì)象的大小不同,因此array類(lèi)型不支持assign,也不允許用花括號(hào)包圍的值列表進(jìn)行賦值。
array<int, 10> a1 = {0,1,2,3,4,5,6,7,8,9};
array<int, 10> a2 = {0}; // 所有元素值均為0
a1 = a2; // 替換a1中的元素
a2 = {0}; // 錯(cuò)誤:不能將一個(gè)花括號(hào)列表賦予數(shù)組
容器賦值運(yùn)算 |
解釋 |
c1=c2 |
將c1中的元素替換為c2中元素的拷貝。c1和c2必須具有相同的類(lèi)型 |
c={a,b,c...} |
將c1中元素替換為初始化列表中元素的拷貝(array不適用) |
swap(c1,c2) |
交換c1和c2中的元素。c1和c2必須具有相同的類(lèi)型。swap通常比從c2向c1拷貝元素快得多 |
—— |
assign操作不適用于關(guān)聯(lián)容器和array |
seq.assign(b,e) |
將seq中的元素替換為迭代器b和e所表示的范圍中的元素。迭代器b和e不能指向seq中的元素 |
seq.assign(il) |
將seq中的元素替換為初始化列表il(initializer_list)中的元素 |
seq.assign(n,t) |
將seq中的元素替換為n個(gè)值為t的元素 |
-
賦值相關(guān)運(yùn)算會(huì)導(dǎo)致指向左邊容器內(nèi)部的迭代器、引用和指針失效。而swap操作將容器內(nèi)容交換不會(huì)導(dǎo)致指向容器的迭代器、引用和指針失效(容器類(lèi)型為array和string的情況除外)。
-
順序容器的assign成員允許我們從一個(gè)不同但相容的類(lèi)型賦值,或者從容器的一個(gè)子序列賦值。assign操作用參數(shù)所指定的元素(的拷貝)替換左邊容器中的所有元素。
list<string> names;
vector<const char*> oldstyle;
names = oldstyle; // 錯(cuò)誤:容器類(lèi)型不匹配
// 正確:可以將const char*轉(zhuǎn)換為string
names.assign(oldstyle.cbegin(), oldstyle.cend());
-
由于其舊元素被替換,因此傳遞給assign的迭代器不能指向調(diào)用assign的容器。
-
除array外,swap不對(duì)任何元素進(jìn)行拷貝、刪除或插入操作,因此可以保證在常數(shù)時(shí)間內(nèi)完成。
-
除string外,指向容器的迭代器、引用和指針在swap操作之后都不會(huì)失效。它們?nèi)灾赶騭wap操作之前所指向的那些元素。但是,在swap之后,這些元素已經(jīng)屬于不同的容器了。對(duì)一個(gè)string調(diào)用swap會(huì)導(dǎo)致迭代器、引用和指針失效。
-
swap兩個(gè)array會(huì)真正交換它們的元素。因此,交換兩個(gè)array所需的時(shí)間與array中元素的數(shù)目成正比。
-
對(duì)于array,在swap操作之后,指針、引用和迭代器所綁定的元素保持不變,但元素值已經(jīng)與另一個(gè)array中對(duì)應(yīng)元素進(jìn)行了交換。
-
在標(biāo)準(zhǔn)庫(kù)中,容器既提供成員函數(shù)版本的swap,也提供非成員版本的swap。非成員版本的swap在泛型編程中是非常重要的。統(tǒng)一使用非成員版本的swap是一個(gè)好習(xí)慣。
-
成員函數(shù)size返回容器中元素的數(shù)目;empty當(dāng)size為0時(shí)返回布爾值true,否則返回false;max_size返回一個(gè)大于或等于該類(lèi)型容器所能容納的最大元素?cái)?shù)的值。forward_list支持max_size和empty,但不支持size。
-
每個(gè)容器類(lèi)型都支持相等運(yùn)算符(==和!=);除了無(wú)序關(guān)聯(lián)容器都支持關(guān)系運(yùn)算符(>、>=、<、<=)。關(guān)聯(lián)運(yùn)算符左右兩邊的運(yùn)算對(duì)象必須是相同類(lèi)型的容器,且必須保存相同類(lèi)型的元素。
-
比較兩個(gè)容器實(shí)際上是進(jìn)行元素的逐對(duì)比較。這些運(yùn)算符的工作方式與string的關(guān)系運(yùn)算類(lèi)似。
- 如果兩個(gè)容器具有相同大小且所有元素都兩兩對(duì)應(yīng)相等,則這兩個(gè)容器相等;否則兩個(gè)容器不等。
- 如果兩個(gè)容器大小不同,但較小容器中每個(gè)元素都等于較大容器中的對(duì)應(yīng)元素,則較小容器小于較大容器。
- 如果兩個(gè)容器都不是另一個(gè)容器的前綴子序列,則它們的比較結(jié)果取決于第一個(gè)不相等的元素的比較結(jié)果。
-
只有當(dāng)其元素類(lèi)型也定義了相應(yīng)的比較運(yùn)算符時(shí),我們才可以使用關(guān)系運(yùn)算符來(lái)比較兩個(gè)容器。
-
容器的相等運(yùn)算符實(shí)際上是使用元素的==運(yùn)算符實(shí)現(xiàn)比較的,而其他關(guān)系運(yùn)算符是使用元素的<運(yùn)算符。如果元素類(lèi)型不支持所需運(yùn)算符,那么保存這種元素的容器就不能使用相應(yīng)的關(guān)系運(yùn)算。
向順序容器添加元素的操作 |
解釋 |
—— |
這些操作會(huì)改變?nèi)萜鞯拇笮。籥rray不支持這些操作 |
—— |
forward_list有自己專(zhuān)有版本的insert和emplace |
—— |
forward_list不支持push_back和emplace_back |
—— |
vector和string不支持push_front和emplace_front |
c.push_back(t)或c.emplace_back(args) |
在c的尾部創(chuàng)建一個(gè)值為t或由args創(chuàng)建的元素。返回void |
c.push_front(t)或c.emplace_front(args) |
在c的頭部創(chuàng)建一個(gè)值為t或由args創(chuàng)建的元素。返回void |
c.insert(p,t)或c.emplace(p,args) |
在迭代器p指向的元素之前創(chuàng)建一個(gè)值為t或由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中的元素(insert會(huì)破壞迭代器)。返回指向新添加的第一個(gè)元素的迭代器;若范圍為空,則返回p |
c.insert(p,il) |
il是一個(gè)花括號(hào)包圍的元素值列表(initializer_list)。將這些給定值插入到迭代器p指向的元素之前。返回指向新添加的第一個(gè)元素的迭代器;若列表為空,則返回p |
-
向一個(gè)vector、string或deque插入元素會(huì)使所有指向容器的迭代器、引用和指針失效。
-
不同容器使用不同的策略來(lái)分配元素空間,而這些策略直接影響性能。
-
當(dāng)我們用一個(gè)對(duì)象來(lái)初始化容器時(shí),或?qū)⒁粋€(gè)對(duì)象插入到容器中時(shí),實(shí)際上放入到容器中的是對(duì)象的一個(gè)拷貝,而不是對(duì)象本身。就像我們將一個(gè)對(duì)象傳遞給非引用參數(shù)一樣,容器中的元素與提供值的對(duì)象之間沒(méi)有任何關(guān)聯(lián)。隨后對(duì)容器中元素的任何改變都不會(huì)影響到原始對(duì)象,反之亦然。
-
通過(guò)使用insert的返回值,可以在容器中一個(gè)特定位置反復(fù)插入元素:
list<string> lst;
auto iter = lst.begin();
while (cin >> word)
iter = lst.insert(iter, word); // 等價(jià)于調(diào)用push_front
-
emplace_front、emplace和emplace_back這些操作構(gòu)造而不是拷貝元素。
-
emplace函數(shù)在容器中直接構(gòu)造元素。傳遞給emplace函數(shù)的參數(shù)必須與元素類(lèi)型的構(gòu)造函數(shù)相匹配。
#include <iostream>
#include <vector>
using namespace std;
class A
{
private:
vector<int> data;
public:
A(vector<int>::iterator beg, vector<int>::iterator end)
{
data.assign(beg, end);
}
void display()
{
for (auto i : data)
cout << i << " ";
cout << endl;
}
};
int main()
{
vector<int> iv{1, 2, 3};
vector<A> one(5, A(iv.begin(), iv.end()));
for (auto i : one)
i.display();
cout << endl;
vector<int> ivv{2, 3, 6};
one.emplace_back(ivv.begin(), ivv.end());
one.back().display();
return 0;
}
-
包括array在內(nèi)的每個(gè)順序容器都有一個(gè)front成員函數(shù),而除forward_list之外的所有順序容器都有一個(gè)back成員函數(shù)。這兩個(gè)操作分別返回首元素和尾元素的引用:
// 在解引用一個(gè)迭代器或調(diào)用front或back之前檢查是否有元素
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迭代器不能執(zhí)行--操作
auto val4 = c.back(); // forward_list不支持
}
-
在調(diào)用front和back(或解引用begin和end返回的迭代器)之前,要確保c非空。如果容器為空,if中操作的行為將是未定義的。
在順序容器中訪(fǎng)問(wèn)元素的操作 |
解釋 |
—— |
at和下標(biāo)操作只適用于string、vector、deque和array |
—— |
back不適用于forward_list |
c.back() |
返回c中尾元素的引用。若c為空,函數(shù)行為未定義。 |
c.front() |
返回c中首元素的引用。若c為空,函數(shù)行為未定義。 |
c[n] |
返回c中下標(biāo)為n的元素的引用,n是一個(gè)無(wú)符號(hào)整數(shù)。若n>=c.size(),則函數(shù)行為未定義 |
c.at(n) |
返回下標(biāo)為n的元素的引用。類(lèi)似下標(biāo)運(yùn)算符,但如果下標(biāo)越界,則拋出一out_of_range 異常 |
-
對(duì)一個(gè)空容器調(diào)用front和back,就像使用一個(gè)越界的下標(biāo)一樣,是一種嚴(yán)重的程序設(shè)計(jì)錯(cuò)誤。
-
在容器中訪(fǎng)問(wèn)元素的成員函數(shù)(即,front、back、下標(biāo)和at)返回的都是引用。如果容器是一個(gè)const對(duì)象,則返回值是const的引用。如果容器不是const的,則返回值是普通引用,我們可以用來(lái)改變?cè)氐闹担?/p>
if (!c.empty())
{
c.front() = 42; // 將42賦予c中的第一個(gè)元素
auto &v = c.back(); // 獲得指向最后一個(gè)元素的引用
v = 1024; // 改變c中的元素
auto v2 = c.back(); // v2不是一個(gè)引用,它是c.back()的一個(gè)拷貝
v2 = 0; // 未改變c中的元素
// 如果我們使用auto變量來(lái)保存這些函數(shù)的返回值,并且希望使用此變量來(lái)改變?cè)氐闹?,必須記得將變量定義為引用類(lèi)型
}
順序容器的刪除操作 |
解釋 |
—— |
這些操作會(huì)改變?nèi)萜鞯拇笮?,所以不適用于array |
—— |
forward_list有特殊版本的erase |
—— |
forward_list不支持pop_back;vector和string不支持pop_front |
c.pop_back() |
刪除c中尾元素。若c為空,則函數(shù)行為未定義。函數(shù)返回void |
c.pop_front() |
刪除c中首元素。若c為空,則函數(shù)行為未定義。函數(shù)返回void |
c.erase(p) |
刪除迭代器p所指定的元素,返回一個(gè)指向被刪元素之后元素的迭代器,若p指向尾元素,則返回尾后迭代器。若p是尾后迭代器,則函數(shù)行為未定義 |
c.erase(b,e) |
刪除迭代器b和e所指定范圍內(nèi)的元素。返回一個(gè)指向最后一個(gè)被刪元素之后元素的迭代器,若e本身就是尾后迭代器,則函數(shù)也返回尾后迭代器(總之返回e) |
c.clear() |
刪除c中的所有元素。返回void |
- 刪除deque中除首尾位置之外的任何元素都會(huì)使所有迭代器、引用和指針失效。指向vector或string中刪除點(diǎn)之后位置的迭代器、引用和指針都會(huì)失效。
- 刪除元素的成員函數(shù)并不檢查其參數(shù)。在刪除元素之前,程序員必須確保它(們)是存在的。
- 在一個(gè)單向鏈表中,沒(méi)有簡(jiǎn)單的辦法來(lái)獲取一個(gè)元素的前驅(qū)。因此,在一個(gè)forward_list中添加或刪除元素的操作是通過(guò)改變給定元素之后的元素來(lái)完成的。為了支持這些操作,forward_list也定義了before_begin,它返回一個(gè)首前迭代器(允許我們添加刪除鏈表首元素)
在forward_list中插入或刪除元素的操作 |
解釋 |
lst.before_begin()或lst.cbefore_begin() |
返回指向鏈表首元素之前不存在的元素的迭代器。此迭代器不能解引用。cbefore_begin() 返回一個(gè)const_iterator |
lst.insert_after(p,t)或lst.insert_after(p,n,t)或lst.insert_after(p,b,e)或lst.insert_after(p,il) |
在迭代器p之后的位置插入元素。t是一個(gè)對(duì)象,n是數(shù)量,b和e是表示范圍的一對(duì)迭代器(b和e不能指向lst內(nèi)),il是一個(gè)花括號(hào)列表(initializer_list )。返回一個(gè)指向最后一個(gè)插入元素的迭代器。如果范圍為空,則返回p。若p為尾后迭代器,則函數(shù)行為未定義 |
emplace_after(p,args) |
使用args在p指定的位置之后創(chuàng)建一個(gè)元素。返回一個(gè)指向這個(gè)新元素的迭代器。若p為尾后迭代器,則函數(shù)行為未定義 |
lst.erase_after(p)或lst.erase_after(b,e) |
刪除p指向的位置之后的元素,或刪除從b之后直到(但不包含)e之間的元素。返回一個(gè)指向被刪元素之后元素的迭代器,若不存在這樣的元素,則返回尾后迭代器。如果p指向lst的尾元素或者是一個(gè)尾后迭代器,則函數(shù)行為未定義 |
// 示例代碼:
forward_list<int> flst = {0,1,2,3,4,5,6,7,8,9};
auto prev = flst.before_begin(); // 表示flst的“首前元素”
auto curr = flst.begin(); // 表示flst中的第一個(gè)元素
while (curr != flst.end()) // 仍有元素要處理
{
if (*curr % 2) // 若元素為奇數(shù),也可以用*curr & 1
curr = flst.erase_after(prev); // 刪除它并移動(dòng)curr
else
{
prev = curr; // 移動(dòng)迭代器curr,指向下一個(gè)元素,prev指向
++curr; // curr之前的元素
}
}
順序容器大小操作 |
解釋 |
—— |
resize不適用于array |
c.resize(n) |
調(diào)整c的大小為n個(gè)元素。若n<c.size(),則多出的元素被丟棄。若必須添加新元素(n>c.size()),對(duì)新元素進(jìn)行值初始化。 |
c.resize(n,t) |
調(diào)整c的大小為n個(gè)元素。任何新添加的元素都初始化為值t |
-
如果resize縮小容器,則指向被刪除元素的迭代器、引用和指針都會(huì)失效;對(duì)vector、string或deque進(jìn)行resize可能導(dǎo)致迭代器、指針和引用失效。
-
容器操作可能使迭代器失效。使用失效的迭代器、指針或引用是嚴(yán)重的運(yùn)行時(shí)錯(cuò)誤。
- 在向容器添加元素后:
- 如果容器是vector或string,且存儲(chǔ)空間被重新分配,則指向容器的迭代器、指針和引用都會(huì)失效。如果存儲(chǔ)空間未重新分配,指向插入位置之前的元素的迭代器、指針和引用仍有效,但指向插入位置之后元素的迭代器、指針和引用將會(huì)失效。
- 對(duì)于deque,插入到除首尾位置之外的任何位置都會(huì)導(dǎo)致迭代器、指針和引用失效。如果在首尾位置添加元素,迭代器會(huì)失效,但指向存在的元素的引用和指針不會(huì)失效。
- 對(duì)于list和forward_list,指向容器的迭代器(包括尾后迭代器和首前迭代器)、指針和引用仍有效。
- 當(dāng)我們從一個(gè)容器中刪除元素后,指向被刪除元素的迭代器、指針和引用一定會(huì)失效,畢竟,這些元素都已經(jīng)被銷(xiāo)毀了。當(dāng)我們刪除一個(gè)元素后:
- 對(duì)于list和forward_list,指向容器其他位置的迭代器(包括尾后迭代器和首前迭代器)、引用和指針仍有效。
- 對(duì)于deque,如果在首尾之外的任何位置刪除元素,那么指向被刪除元素外其他元素的迭代器、引用和指針也會(huì)失效。如果是刪除deque的尾元素,則尾后迭代器也會(huì)失效,但其他迭代器、引用和指針不受影響;如果是刪除首元素,這些也不會(huì)受影響。
- 對(duì)于vector和string,指向被刪元素之前元素的迭代器、引用和指針仍有效。注意:當(dāng)我們刪除元素時(shí),尾后迭代器總是會(huì)失效。
-
當(dāng)你使用迭代器(或指向容器元素的引用或指針)時(shí),最小化要求迭代器必須保持有效的程序片段是一個(gè)好的辦法。由于向迭代器添加元素和從迭代器刪除元素的代碼可能會(huì)使迭代器失效,因此必須保證每次改變?nèi)萜鞯牟僮髦蠖颊_地重新定位迭代器。這個(gè)建議對(duì)vector、string和deque尤為重要。
-
程序必須保證每個(gè)循環(huán)布中都更新迭代器、引用和指針:
// 傻瓜循環(huán),刪除偶數(shù)元素,復(fù)制每個(gè)奇數(shù)元素
vector<int> vi = {0,1,2,3,4,5,6,7,8,9};
auto iter = vi.begin(); // 調(diào)用begin而不是cbegin,因?yàn)槲覀円淖僾i
while (iter != vi.end())
{
if (*iter % 2)
{
iter = vi.insert(iter, *iter); // 復(fù)制當(dāng)前元素
iter += 2; // 向前移動(dòng)迭代器,跳過(guò)插入到它之前的元素以及當(dāng)前元素
}
else
{
iter = vi.erase(iter); // 刪除偶數(shù)元素
// 不應(yīng)向前移動(dòng)迭代器,iter指向我們刪除的元素之后的元素
}
}
-
不要保存end返回的迭代器。當(dāng)我們添加、刪除vector或string的元素后,或在deque中首元素之外任何位置添加、刪除元素后,原來(lái)end返回的迭代器總是會(huì)失效。因此,添加或刪除元素的循環(huán)程序必須反復(fù)調(diào)用end,而不能在循環(huán)之前保存end返回的迭代器,一直當(dāng)作容器末尾使用。
容器大小管理操作 |
解釋 |
—— |
shrink_to_fit只適用于vector、string和deque |
—— |
capacity和reserve只適用于vector和string |
c.shrink_to_fit() |
請(qǐng)將capacity()減少為與size()相同大小(具體的實(shí)現(xiàn)可以選擇忽略此請(qǐng)求,即,調(diào)用shrink_to_fit并不保證一定退回內(nèi)存空間) |
c.capacity() |
不重新分配內(nèi)存空間的話(huà),c可以保存多少元素 |
c.reserve(n) |
分配至少能容納n個(gè)元素的內(nèi)存空間 |
-
reserve并不改變?nèi)萜髦性氐臄?shù)量,它僅影響vector預(yù)先分配多大的內(nèi)存空間。只有當(dāng)需要的內(nèi)存空間超過(guò)當(dāng)前容量時(shí),reserve調(diào)用才會(huì)改變vector的容量,如果需求大小大于當(dāng)前容量,reserve至少分配與需求一樣大的內(nèi)存空間(可能更大)。如果需求大小小于或等于當(dāng)前容量,reserve什么也不做。特別是,當(dāng)需求大小小于當(dāng)前容量時(shí),容器不會(huì)退回內(nèi)存空間。因此,在調(diào)用reserve之后,capacity將會(huì)大于或等于傳遞給reserve的參數(shù)。這樣,調(diào)用reserve永遠(yuǎn)也不會(huì)減少容器占用的內(nèi)存空間。類(lèi)似的,resize成員函數(shù)只能改變?nèi)萜髦性氐臄?shù)目,而不是容器的容量。我們同樣不能使用resize來(lái)減少容器預(yù)留的內(nèi)存空間。
-
每個(gè)vector實(shí)現(xiàn)都可以選擇自己的內(nèi)存分配策略。但是必須遵守的一條原則是:只有當(dāng)迫不得已(在執(zhí)行insert操作時(shí)size與capacity相等,或者調(diào)用resize或reserve時(shí)給定的大小超過(guò)當(dāng)前capacity)時(shí)才可以分配新的內(nèi)存空間。
構(gòu)造string的其他方法 |
解釋 |
—— |
n、len2和pos2都是無(wú)符號(hào)值 |
string s(cp,n) |
s是cp指向的數(shù)組中前n個(gè)字符的拷貝。此數(shù)組至少應(yīng)該包含n個(gè)字符 |
string s(s2,pos2) |
s是string s2從下標(biāo)pos2開(kāi)始的字符的拷貝。若pos2>s2.size(),構(gòu)造函數(shù)的行為未定義 |
string s(s2,pos2,len2) |
s是string s2從下標(biāo)pos2開(kāi)始len2個(gè)字符的拷貝。若pos2>s2.size(),構(gòu)造函數(shù)的行為未定義。不管len2的值是多少,構(gòu)造函數(shù)至多拷貝s2.size()-pos2個(gè)字符。 |
子字符串操作 |
解釋 |
s.substr(pos,n) |
返回一個(gè)string,包含s中從pos開(kāi)始的n個(gè)字符的拷貝。pos的默認(rèn)值為0.n的默認(rèn)值為s.size()-pos,即拷貝從pos開(kāi)始的所有字符 |
- 在c++11中,vector 增加了data()的用法,它返回內(nèi)置vecotr所指的數(shù)組內(nèi)存的第一個(gè)元素的指針。
修改string的操作 |
解釋 |
s.insert(pos,args) |
在pos之前插入args指定的字符。pos可以是一個(gè)下標(biāo)或一個(gè)迭代器。接受下標(biāo)的版本返回一個(gè)指向s的引用;接受迭代器的版本返回指向第一個(gè)插入字符的迭代器 |
s.erase(pos,len) |
刪除從位置pos開(kāi)始的len個(gè)字符。如果len被省略,則刪除從pos開(kāi)始直至s末尾的所有字符。返回一個(gè)指向s的引用 |
s.assign(args) |
將s中的字符替換為args指定的字符。返回一個(gè)指向s的引用 |
s.append(args) |
將args追加到s。返回一個(gè)指向s的引用 |
s.replace(range,args) |
刪除s中范圍range內(nèi)的字符,替換為args指定的字符。range或者是一個(gè)下標(biāo)和一個(gè)長(zhǎng)度,或者是一對(duì)指向s的迭代器。返回一個(gè)指向s的引用 |
—— |
args可以是下列形式之一;append和assign可以使用所有形式 |
—— |
str不能與s相同,迭代器b和e不能指向s |
str |
字符串str |
str,pos,len |
str中從pos開(kāi)始最多l(xiāng)en個(gè)字 |
cp,len |
從cp(char pointer)指向的字符數(shù)組的前(最多)len個(gè)字符 |
n,c |
n個(gè)字符c |
b,e |
迭代器b和e指定的范圍內(nèi)的字符 |
初始化列表 |
花括號(hào)包圍的,以逗號(hào)分隔的字符列表 |
—— |
replace和insert所允許的args形式依賴(lài)于range和pos是如何指定的 |
replace(pos,len,args) |
replace(b,e,args) |
insert(pos,args) |
insert(iter,args) |
args可以是 |
是 |
是 |
是 |
否 |
str |
是 |
否 |
是 |
否 |
str,pos,len |
是 |
是 |
是 |
否 |
cp,len |
是 |
是 |
否 |
否 |
cp |
是 |
是 |
是 |
是 |
n,c |
否 |
是 |
否 |
是 |
b2,e2 |
否 |
是 |
否 |
是 |
初始化列表 |
- string搜索函數(shù)返回string::size_type值,該類(lèi)型是一個(gè)unsigned類(lèi)型。因此,用一個(gè)int或其他帶符號(hào)類(lèi)型來(lái)保存這些函數(shù)的返回值不是一個(gè)好主意。
string搜索操作 |
解釋 |
—— |
搜索操作返回指定字符出現(xiàn)的下標(biāo),如果未找到則返回npos |
s.find(args) |
查找s中args第一次出現(xiàn)的位置 |
s.rfind(args) |
查找s中args最后一次出現(xiàn)的位置 |
s.find_first_of(args) |
在s中查找args中任何一個(gè)字符第一次出現(xiàn)的位置 |
s.find_last_of(args) |
在s中查找args中任何一個(gè)字符最后一次出現(xiàn)的位置 |
s.find_first_not_of(args) |
在s中查找第一個(gè)不在args中的字符 |
s.find_last_not_of(args) |
在s中查找最后一個(gè)不在args中的字符 |
—— |
args必須是以下形式之一 |
c,pos |
從s中位置pos開(kāi)始查找字符c。pos默認(rèn)為0 |
s2,pos |
從s中位置pos開(kāi)始查找字符串s2。pos默認(rèn)為0 |
cp,pos |
從s中位置pos開(kāi)始查找指針cp指向的以空字符結(jié)尾的C風(fēng)格字符串 |
cp,pos,n |
從s中位置pos開(kāi)始查找指針cp指向的數(shù)組的前n個(gè)字符。pos和n無(wú)默認(rèn)值 |
-
指定在哪里開(kāi)始搜索:
string numbers("0123456789"), name("r2d2");
string::size_type pos = 0;
// 每步循環(huán)查找name中下一個(gè)數(shù)
while ((pos = name.find_first_of(numbers, pos)) != string::npos)
{
cout << "found number at index: " << pos
<< " element is " << name[pos] << endl;
++pos; // 移動(dòng)到下一個(gè)字符
}
s.compare的幾種參數(shù)形式 |
解釋 |
s2 |
比較s和s2 |
pos1,n1,s2 |
將s中從pos1開(kāi)始的n1個(gè)字符與s2進(jìn)行比較 |
pos1,n1,s2,pos2,n2 |
將s中從pos1開(kāi)始的n1個(gè)字符與s2中從pos2開(kāi)始的n2個(gè)字符進(jìn)行比較 |
cp |
比較s與cp指向的以空字符結(jié)尾的字符數(shù)組 |
pos1,n1,cp |
將s中從pos1開(kāi)始的n1個(gè)字符與cp指向的以空字符結(jié)尾的字符數(shù)組進(jìn)行比較 |
pos1,n1,cp,n2 |
將s中從pos1開(kāi)始的n1個(gè)字符與指針cp指向的地址開(kāi)始的n2個(gè)字符進(jìn)行比較 |
string和數(shù)值之間的轉(zhuǎn)換 |
解釋 |
to_string(val) |
一組重載函數(shù),返回?cái)?shù)值val的string表示。val可以是任何算術(shù)類(lèi)型。對(duì)每個(gè)浮點(diǎn)類(lèi)型和int或更大的整型,都有相應(yīng)版本的to_string。與往常一樣,小整型會(huì)被提升 |
stoi(s,p,b)或stol(s,p,b)或stoul(s,p,b)或stoll(s,p,b)或stoull(s,p,b) |
返回s的起始子串(表示整數(shù)內(nèi)容)的數(shù)值,返回值類(lèi)型分別是int、long、unsigned long、long long、unsigned long long。b表示轉(zhuǎn)換所用的基數(shù),默認(rèn)值為10。p是size_t指針,用來(lái)保存s中第一個(gè)非數(shù)值字符的下標(biāo),p默認(rèn)為0,即,函數(shù)不保存下標(biāo) |
stof(s,p)或stod(s,p)或stold(s,p) |
返回s的起始子串(表示浮點(diǎn)數(shù)內(nèi)容)的數(shù)值,返回值類(lèi)型分別是float、double、或long double。參數(shù)p的作用與整數(shù)轉(zhuǎn)換函數(shù)中一樣 |
—— |
string參數(shù)中第一個(gè)非空白符必須是符號(hào)(+或-)或數(shù)字。它可以以0x或0X開(kāi)頭來(lái)表示十六進(jìn)制數(shù)。對(duì)那些將字符串轉(zhuǎn)換為浮點(diǎn)值的函數(shù),string參數(shù)也可以以小數(shù)點(diǎn)(.)開(kāi)頭,并可以包含e或E來(lái)表示指數(shù)部分。對(duì)于那些將字符串轉(zhuǎn)換為整型值的函數(shù),根據(jù)基數(shù)不同,string參數(shù)可以包含字母字符,對(duì)應(yīng)大于數(shù)字9的數(shù)。 |
—— |
如果string不能轉(zhuǎn)換為一個(gè)數(shù)值,這些函數(shù)拋出一個(gè)invalid_argument 異常。如果轉(zhuǎn)換得到的數(shù)值無(wú)法用任何類(lèi)型來(lái)表示,則拋出一個(gè)out_of_range 異常。 |
- 適配器是標(biāo)準(zhǔn)庫(kù)中的一個(gè)通用概念。本質(zhì)上,一個(gè)適配器是一種機(jī)制,能使某種事物的行為看起來(lái)像另外一種事物一樣。一個(gè)容器適配器接受一種已有的容器類(lèi)型,是其行為看起來(lái)像一種不同的類(lèi)型。
所有容器適配器都支持的操作和類(lèi)型 |
解釋 |
size_type |
一種類(lèi)型,足以保存當(dāng)前類(lèi)型的最大對(duì)象的大小 |
value_type |
元素類(lèi)型 |
container_type |
實(shí)現(xiàn)適配器的底層容器類(lèi)型 |
A a; |
創(chuàng)建一個(gè)名為a的空適配器 |
A a(c); |
創(chuàng)建一個(gè)名為a的適配器,帶有容器c的一個(gè)拷貝 |
關(guān)系運(yùn)算符 |
每個(gè)適配器都支持所有關(guān)系運(yùn)算符:==、!=、<、<=、>、>=。這些運(yùn)算符返回底層容器的比較結(jié)果 |
a.empty() |
若a包含任何元素,返回false,否則返回true |
a.size() |
返回a中的元素?cái)?shù)目 |
swap(a,b) |
交換a和b的內(nèi)容,a和b必須有相同類(lèi)型,包括底層容器類(lèi)型也必須相同 |
-
默認(rèn)情況下,stack和queue是基于deque實(shí)現(xiàn)的,priority_queue是在vector之上實(shí)現(xiàn)的。我們可以在創(chuàng)建一個(gè)適配器時(shí)將一個(gè)命名的順序容器作為第二個(gè)類(lèi)型參數(shù),來(lái)重載默認(rèn)容器類(lèi)型。
// 從deq拷貝元素到stk
stack<int> stk(deq);
// 在vector上實(shí)現(xiàn)的空棧
stack<string, vector<string>> str_stk;
// str_stk2在vector上實(shí)現(xiàn),初始化時(shí)保存svec的拷貝
stack<string, vector<string>> str_stk2(svec); // svec是vector<string>類(lèi)型
額外的棧操作 |
解釋 |
—— |
棧默認(rèn)基于deque實(shí)現(xiàn),也可以在list或vector之上實(shí)現(xiàn)。 |
s.pop() |
刪除棧頂元素,但不返回該元素值 |
s.push(item) |
創(chuàng)建一個(gè)新元素壓入棧頂,該元素通過(guò)拷貝或移動(dòng)item而來(lái),或者由args構(gòu)造 |
s.top() |
返回棧頂元素,但不將元素彈出棧 |
額外的queue和priority_queue操作 |
解釋 |
—— |
queue默認(rèn)基于deque實(shí)現(xiàn),priority_queue默認(rèn)基于vector實(shí)現(xiàn) |
—— |
queue也可以用list或vector實(shí)現(xiàn),priority_queue也可以用deque實(shí)現(xiàn) |
q.pop() |
彈出queue的首元素或priority_queue的最高優(yōu)先級(jí)的元素,但不返回此元素 |
q.front() |
返回首元素或尾元素,但不刪除此元素 |
q.back() |
只適用于queue |
q.top() |
返回最高優(yōu)先級(jí)元素,但不刪除該元素 |
q.push(item)或q.emplace(args) |
在queue末尾或priority_queue中恰當(dāng)?shù)奈恢脛?chuàng)建一個(gè)元素,其值為item,或者由args構(gòu)造 |
- deque支持在容器頭尾位置的快速插入和刪除,而且在兩端插入或刪除元素都不會(huì)導(dǎo)致重新分配空間。
|