C++ vector的使用

參考:http://www.cplusplus.com/reference/vector/vector/?kw=vectorios

 

std::vector (C++11)算法

template < class T, class Alloc = allocator<T> > class vector; // generic template

Vectors是一個序列容器,表示大小可變的數組後端

就像數組同樣,vectors(向量)爲其元素使用連續的存儲位置,這意味着它們的元素也能夠經過指向其元素的常規指針上的偏移量來訪問,而且與數組同樣有效。但與數組不一樣的是,它們的大小能夠動態變化,容器會自動處理它們的存儲。數組

在內部,向量使用動態分配的數組來存儲它們的元素。這是由於爲了在插入新元素時增大大小,可能須要從新分配這個數組,這意味着分配一個新數組並將全部元素移動到新數組中。就處理時間而言,這是一個相對昂貴的任務,所以,向量不會在每次向容器添加元素時從新分配。less

相反,向量容器可能會分配一些額外的存儲空間以適應可能的增加,所以容器的實際容量可能會大於存儲元素所需的存儲空間(即它的大小)。庫能夠實現不一樣的增加策略來平衡內存使用和從新分配,但在任何狀況下,從新分配應該只發生在對數生長間隔的大小,以便插入單個元素的向量能夠提供平攤常數時間複雜度(見push_back方法)。函數

所以,與數組相比,向量消耗更多的內存,以換取管理存儲和有效地動態增加的能力。性能

與其餘動態序列容器(deques、lists和forward_lists)相比,vector很是高效地訪問它的元素(就像數組同樣),而且相對高效地從它的末端添加或刪除元素。對於涉及在非結尾位置插入或刪除元素的操做,它們的性能比其餘操做差,並且與lists和forward_lists相比,它們的迭代器和引用的一致性更差。測試

 

Container properties屬性

Sequence序列

序列容器中的元素按嚴格的線性順序排列。各個元素經過它們在這個序列中的位置來訪問。優化

Dynamic array動態數組

容許直接訪問序列中的任何元素,甚至是經過指針運算,並在序列末尾提供相對快速的元素添加/刪除。ui

Allocator-aware

容器使用一個分配器對象來動態地處理它的存儲需求。

 

Template parameters模版參數

  • T:元素類型。只有在T被保證在移動時不拋出異常時,實現才能優化移動元素,而不是在從新分配期間複製它們。別名爲成員類型vector::value_type。
  • Alloc:用於定義存儲分配模型的分配器對象的類型。默認狀況下,使用的是分配器類模板,它定義了最簡單的內存分配模型,而且是與值無關的。

別名爲成員類型vector::allocator_type。

 

Member types成員類型

成員類型  定義  notes
value_type 第一個模版參數T  
allocator_type 第二個模版參數Alloc 默認爲allocator<value_type>
reference value_type&,引用  
const_reference const value_type&  
pointer allocator_traits<allocator_type>::pointer 用於默認allocator:value_type*
const_pointer allocator_traits<allocator_type>::const_pointer 用於默認allocator:const value_type*
iterator 一個value_type的隨機訪問迭代器 可轉換成const_iterator
const_iterator 一個const value_type的隨機訪問迭代器  
reverse_iterator reverse_iterator<iterator>  
const_reverse_iterator reverse_iterator<const_iterator>  
difference_type 一種有符號整數類型,等價於:iterator_traits<iterator>::difference_type 一般是ptrdiff_t
size_type 一個無符號整數類型,它能夠表示任意一個非負的size_type類型的值 一般是size_t

 

 

Member functions成員函數

1)構造函數,有多態

default (1)    
explicit vector (const allocator_type& alloc = allocator_type());

fill (
2) explicit vector (size_type n); vector (size_type n, const value_type& val, const allocator_type& alloc = allocator_type());
range (
3) template <class InputIterator> vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
copy (
4) vector (const vector& x); vector (const vector& x, const allocator_type& alloc);
move (
5) vector (vector&& x); vector (vector&& x, const allocator_type& alloc);
initializer list (
6) vector (initializer_list<value_type> il, const allocator_type& alloc = allocator_type());

 構造一個vector向量,根據使用的構造器版原本初始化其內容

 

解釋:

(1)empty container constructor (default constructor)空容器構造器,也是默認構造器

構造一個沒有元素的空容器

(2) fill constructor

構造一個有着n個元素的容器。每一個元素都是val(若是提供)的複製

(3) range constructor

用與range[first,last)相同的元素構造一個容器,每一個元素都是由該範圍中相應的元素按相同的順序構造的。

(4) copy constructor (and copying with allocator)

構造一個獲取x元素的容器。
若是指定了alloc,而且它與x的分配器不一樣,則移動元素。不然,不會構造任何元素(它們的全部權直接轉移)。
x處於未指定但有效的狀態。

(6) initializer list constructor
用il中每一個元素的副本以相同的順序構造一個容器。
容器保存一個alloc的內部副本,該副本用於爲它的元素分配和釋放存儲,並構造和銷燬它們(由它的allocator_traits指定)。若是沒有alloc參數傳遞給構造函數,則使用默認構造的分配器,除了如下狀況:
  • 複製構造函數(4,第一個簽名,即第一種沒alloc的方式)建立一個容器,該容器經過調用x的分配器上適當的selected_on_container_copy_construction trait來保存和使用分配器的副本。
  • move構造函數(5,第一個簽名)得到x的分配器。

經過調用帶有適當參數的allocator_traits::construct來複制、移動或以其餘方式構造全部元素。

 

參數:

1) alloc:

分配器對象。
容器保存並使用這個分配器的內部副本。
成員類型allocator_type是容器使用的內部分配器類型,在vector中定義爲其第二個模板參數(Alloc)的別名。
若是allocator_type是默認分配器的實例化(它沒有狀態),這就可有可無了。

2) n:

初始容器大小(即,在構造時容器中的元素數)。
成員類型size_type是無符號整數類型。

3) val:

要填充容器的值。容器中的n個元素都將被初始化爲該值的一個副本。
成員類型value_type是容器中元素的類型,在vector中定義爲其第一個模板參數(T)的別名。

4) first, last:
將迭代器輸入到範圍的初始和最終位置。使用的範圍是[first,last),它包括first和last之間的全部元素,包括first指向的元素,但不包括last指向的元素。
函數模板參數InputIterator應該是一個輸入迭代器類型,它指向能夠構造value_type對象的類型的元素。

5) x:

另外一個相同類型的向量對象(具備相同的類模板參數T和Alloc),其內容要麼被複制,要麼被獲取。

6) il:
一個initializer_list對象。
這些對象是由初始化器列表聲明器自動構造的。
成員類型value_type是容器中元素的類型,在vector中定義爲其第一個模板參數(T)的別名。
例子:
#include <iostream>
#include <vector>
using namespace std;

int main(){
    //如上面所述的相同順序來使用構造器
    vector<int> first; //ints的空vector
    vector<int> second (4, 100); //4個值爲100的ints
    vector<int> third (second.begin(), second.end()); //迭代second
    vector<int> fourth (third); //third的副本

    int myints[] = {16, 2, 77, 29};
    //迭代器構造器也能夠用來構造數組,即第三種構造器的另外一種寫法:
    vector<int> fifth(myints, myints + sizeof(myints) / sizeof(int));

    cout << "the contents of first are : ";
    for(auto x : first)
        cout << ' ' << x;
    cout << '\n';

    cout << "the contents of second are : ";
    for(auto x : second)
        cout << ' ' << x;
    cout << '\n';

    cout << "the contents of third are : ";
    for(auto x : third)
        cout << ' ' << x;
    cout << '\n';

    cout << "the contents of fourth are : ";
    for(auto x : fourth)
        cout << ' ' << x;
    cout << '\n';

    cout << "the contents of fourth are : ";
    for(vector<int>::iterator it = fourth.begin(); it!=fourth.end(); ++it)
        cout << ' ' << *it;
    cout << '\n';

    cout << "the contents of fifth are : ";
    for(vector<int>::iterator it = fifth.begin(); it!=fifth.end(); ++it)
        cout << ' ' << *it;
    cout << '\n';

    return 0;
}

返回:

/Users/user/CLionProjects/untitled/cmake-build-debug/untitled
the contents of first are : 
the contents of second are :  100 100 100 100
the contents of third are :  100 100 100 100
the contents of fourth are :  100 100 100 100
the contents of fourth are :  100 100 100 100
the contents of fifth are :  16 2 77 29

Process finished with exit code 0

 

Complexity複雜度

對於默認構造函數(1)和移動構造函數(5)來講容器複雜度是常量(除非alloc與x的分配器不一樣)。
對於全部其餘狀況,結果容器大小是線性的。
此外,若是range構造函數(3)中的InputIterator不是前向迭代器類別(即,它只是一個輸入迭代器),則不能預先肯定新的容量,並且構造在大小上將帶來額外的對數複雜度(在增加時從新分配)。

 

Iterator validity迭代有效性

move constructors (5)中,若是元素被移動,那麼與x相關的全部迭代器、指針和引用都將無效。

 

Data races

訪問全部複製的元素。
移動構造函數(5)修改x。

 

Exception safety

強保證:在拋出異常時沒有效果。
若是元素結構的適當參數不支持allocator_traits::construct,或者[first,last)指定的範圍無效,它會致使未定義的行爲。

 

2)析構函數

~vector();

銷燬容器對象

這將對包含的每一個元素調用allocator_traits::destroy,並使用它的分配器釋放向量分配的全部存儲容量。

Complexity複雜度

vector::size的線性

Iterator validity

全部的迭代器、指針和引用都無效。

Data races

修改容器及其全部元素。

Exception safety

No-throw guarantee: 從不拋出異常

 

3)賦值操做

copy (1)    
vector& operator= (const vector& x);
move (
2) vector& operator= (vector&& x);
initializer list (
3) vector& operator= (initializer_list<value_type> il);

將新內容分配給容器,替換其當前內容,並相應地修改其大小。

解釋:

複製賦值(1)將x中的全部元素複製到容器中(x保留其內容)。

移動賦值(2)將x的元素移動到容器中(x處於未指定但有效的狀態)。

初始化器列表賦值(3)將il的元素複製到容器中。

容器保留其當前分配器,除非allocator traits(分配器特徵)代表x的分配器應該傳播。若是發生了從新分配,則使用這個分配器(經過它的特性)來分配和釋放存儲,若是須要,則構造或銷燬元素。

在調用以前容器中保存的任何元素要麼被賦值,要麼被銷燬。

 

參數:

x:

一個相同類型的向量對象。(使用相同的模板參數,T和Alloc)。

il:

一個initializer_list對象。編譯器將從初始化器列表聲明器自動構造這些對象。
成員類型value_type是容器中元素的類型,在vector中定義爲其第一個模板參數(T)的別名。

 

返回值:

*this

 

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main(){
    vector<int> foo (3,0);
    vector<int> bar (5,0);

    bar = foo;
    foo = vector<int>();

    cout << "size of foo : " << int(foo.size()) << endl;
    cout << "size of bar : " << int(bar.size()) << endl;
}

返回:

size of foo : 0
size of bar : 3

 

迭代器:

4)begin

      iterator begin() noexcept;
const_iterator begin() const noexcept;

返回迭代器開始
返回一個迭代器,該迭代器指向向量中的第一個元素。
注意,與成員vector::front返回對第一個元素的引用不一樣,這個函數返回一個指向它的隨機訪問迭代器。
若是容器爲空,則不該取消對返回的迭代器值的引用。

 

參數:None

返回值:

序列容器開頭的迭代器。
若是vector對象是const限定的,則該函數返回一個const_iterator。不然,它返回一個iterator。
成員類型iterator和const_iterator是隨機訪問迭代器類型(分別指向一個元素和一個const元素)。

 

5)end

      iterator end() noexcept;
const_iterator end() const noexcept;

返回迭代器結束
返回一個迭代器,該迭代器引用向量容器中的結束符元素。
後端元素是向量中最後一個元素以後的理論元素。它不指向任何元素,所以不該取消引用。
由於標準庫函數使用的範圍不包括它們的結束迭代器所指向的元素,因此這個函數經常與vector::begin結合使用,以指定一個範圍,包括容器中的全部元素。
若是容器爲空,則此函數返回與vector::begin相同的結果

 

參數:None

返回值:

一個迭代器,迭代到序列末尾以後的元素。
若是vector對象是const限定的,則該函數返回一個const_iterator。不然,它返回一個迭代器。
成員類型iterator和const_iterator是隨機訪問迭代器類型(分別指向一個元素和一個const元素)。

 

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main(){
    vector<int> myvector;
    for(int i=1; i<=5; i++) myvector.push_back(i);
    cout << "myvector contains: ";

    for(vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
        cout << ' ' << *it;
    cout << endl;
}

返回:

myvector contains:  1 2 3 4 5

 

6)rbegin

      reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;

返回反向迭代器以反向開始
返回一個反向迭代器,指向向量中的最後一個元素(它的開頭正好相反)。
反向迭代器向後迭代:增長它們則是將它們移到容器的開頭。
rbegin指向成員端將要指向的元素以前的元素。

注意,與成員vector::back返回對同一元素的引用不一樣,此函數返回一個反向隨機訪問迭代器。

參數:None

返回值:

序列容器的反向開頭的反向迭代器。
若是vector對象是const限定的,則該函數返回一個const_reverse_iterator。不然,它將返回一個reverse_iterator。
成員類型reverse_iterator和const_reverse_iterator是反向隨機訪問迭代器類型(分別指向一個元素和一個const元素)。參見向量成員類型。

 

7)rend

      reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;

返回反向迭代器到反向結束
返回一個反向迭代器,指向向量中第一個元素以前的理論元素(被認爲是它的反向端)。
vector::rbegin和vector::rend之間的範圍包含向量的全部元素(按相反的順序)。

參數:None

返回值:

序列容器的反向末端的反向迭代器。
若是vector對象是const限定的,則該函數返回一個const_reverse_iterator。不然,它將返回一個reverse_iterator。
成員類型reverse_iterator和const_reverse_iterator是反向隨機訪問迭代器類型(分別指向一個元素和一個const元素)。參見向量成員類型vector member types.。

 

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main(){
    vector<int> myvector(5); //5個0
    int i=0;

    cout << "myvector contains: ";
    for(vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
        cout << ' ' << *it;
    cout << '\n';

    vector<int>::reverse_iterator rit = myvector.rbegin();
    for(;rit!=myvector.rend(); ++rit) //從後往前疊加
        *rit = ++i;

    cout << "myvector contains: ";
    for(vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
        cout << ' ' << *it;
    cout << '\n';

    return 0;
}

返回:

myvector contains:  0 0 0 0 0
myvector contains:  5 4 3 2 1

 

8) cbegin-內容不能修改

const_iterator cbegin() const noexcept;

返回const_iterator開始
返回一個指向容器中第一個元素的const_iterator。

常量迭代器是指向const內容的迭代器。這個迭代器能夠增長或減小(除非它自己也是const),就像vector::begin返回的迭代器同樣,可是它不能用來修改它所指向的內容,即便vector對象自己不是const
若是容器爲空,則不該取消對返回的迭代器值的引用。

參數:None

返回值:

序列開頭的const_iterator。
成員類型const_iterator是指向const元素的隨機訪問迭代器類型。

 

9)cend

const_iterator cend() const noexcept;

返回const_iterator結束
返回一個指向容器中粘貼結束元素的const_iterator。
常量迭代器是指向const內容的迭代器。這個迭代器能夠增長或減小(除非它自己也是const),就像vector::end返回的迭代器同樣,可是它不能用來修改它所指向的內容,即便vector對象自己不是const。
若是容器爲空,則此函數返回與vector::cbegin相同的結果。
返回的值不能取消引用。

參數:None

返回值:

序列末尾以後的元素的const_iterator。
成員類型const_iterator是指向const元素的隨機訪問迭代器類型。

 

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main(){
    vector<int> myvector = {10,0,30,40,50};

    cout << "myvector contains: ";
    for(vector<int>::const_iterator it = myvector.cbegin(); it!=myvector.cend(); ++it)
        cout << ' ' << *it;
    cout << '\n';

    return 0;
}

返回:

myvector contains:  10 0 30 40 50

 

10)crbegin

const_reverse_iterator crbegin() const noexcept;

返回const_reverse_iterator到反轉開始處
返回一個指向容器中最後一個元素的const_reverse_iterator(即,它的開頭正好相反)。

參數:None

返回值:

序列開頭相反的const_reverse_iterator。
成員類型const_reverse_iterator是指向const元素的反向隨機訪問迭代器類型(請參閱向量成員類型)。

 

11)crend

const_reverse_iterator crend() const noexcept;

將const_reverse_iterator返回到反向終端
返回一個指向容器中第一個元素以前的理論元素的const_reverse_iterator(它被認爲是容器的反向端)。

參數:None

返回值:

序列末尾的const_reverse_iterator。
成員類型const_reverse_iterator是指向const元素的反向隨機訪問迭代器類型(請參閱向量成員類型)。

 

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main(){
    vector<int> myvector = {10,20,30,40,50};

    cout << "myvector backwards: ";
    for(vector<int>::const_reverse_iterator it = myvector.crbegin(); it!=myvector.crend(); ++it)
        cout << ' ' << *it;
    cout << '\n';

    return 0;
}

返回:

myvector backwards:  50 40 30 20 10

 

Capacity:

12)size

size_type size() const noexcept;

返回的大小
返回向量中元素的數目。
這是向量中實際持有的對象的數量,不必定等於它的存儲容量

參數:None

返回值:

容器中元素的數量。
成員類型size_type是無符號整數類型。

 

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myints;
    cout << "0.size " << myints.size() << endl;

    //放入10個值
    for (int i = 0; i < 10; i++) myints.push_back(i);
    cout << "1.size " << myints.size() << endl;

    //插入10個值爲100的ints
    myints.insert(myints.end(), 10, 100);
    cout << "2.size " << myints.size() << endl;

    myints.pop_back();
    cout << "3.size " << myints.size() << endl;

    for(auto x : myints)
        cout << x << ' ';
    cout <<endl;
    return 0;
}

返回:

0.size 0
1.size 10
2.size 20
3.size 19
0 1 2 3 4 5 6 7 8 9 100 100 100 100 100 100 100 100 100 

 

13)max_size

size_type max_size() const noexcept;

返回最大大小
返回向量能夠容納的元素的最大數目。
因爲已知的系統或庫實現的限制,這是容器可以達到的最大潛在大小,可是容器並不能保證可以達到這個大小:它仍然可能在達到這個大小以前的任何一點分配存儲。

參數:None

返回值:

向量容器能夠容納的元素的最大數量。
成員類型size_type是無符號整數類型。

 

14)capacity

size_type capacity() const noexcept;

返回分配的存儲容量大小
返回當前分配給向量的存儲空間的大小,以元素的形式表示。
這個容量不必定等於向量的大小。它能夠等於或更大,容許容納增加的額外空間,而不須要在每次插入時從新分配。
請注意,此容量並不假設對向量的大小有限制。當這個容量用完而且須要更多容量時,容器會自動擴展它(從新分配它的存儲空間)向量大小的理論極限由成員max_size給出

向量的容量能夠經過調用成員vector::reserve來顯式地改變。

參數:None

返回值:

向量中當前分配的存儲容量的大小,以它能夠容納的元素的數量來度量。
成員類型size_type是無符號整數類型。

 

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector;
    for(int i=0; i<100; i++) myvector.push_back(i);

    cout << "size : " << myvector.size() << endl;
    cout << "capacity : " << myvector.capacity() << endl;
    cout << "max_size : " << myvector.max_size() << endl;
    return 0;
}

返回:

size : 100
capacity : 128
max_size : 4611686018427387903

 

15)resize

void resize (size_type n);
void resize (size_type n, const value_type& val);

改變尺寸
調整容器的大小,使其包含n個元素。
若是n小於當前容器的大小,則將內容縮減爲它的前n個元素,刪除其餘元素(並銷燬它們)。
若是n大於當前容器的大小,則經過在末尾插入儘量多的元素來擴展內容,以達到n的大小。若是指定了val,則將新元素初始化爲val的副本,不然,它們將被初始化爲0值。
若是n也大於當前容器容量,則會自動從新分配分配的存儲空間。
注意,這個函數經過插入或刪除容器中的元素來更改容器的實際內容。

參數:

n:

新的容器大小,用元素的數量表示。
成員類型size_type是無符號整數類型。

val:

若是n大於當前容器大小,則將該val對象的內容複製到添加的元素中。
若是未指定,則使用默認構造函數。
成員類型value_type是容器中元素的類型,在vector中定義爲第一個模板參數(T)的別名。

 

返回值:none

若是發生了從新分配,則使用容器的分配器分配存儲,這可能會在失敗時拋出異常(對於默認分配器,若是分配請求沒有成功,則拋出bad_alloc)。

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector;
    for(int i=1; i<10; i++) myvector.push_back(i);
    //從9截斷爲5
    myvector.resize(5);
    //從5擴爲8,賦值爲100
    myvector.resize(8,100);
    //從8擴爲12,默認賦值爲0
    myvector.resize(12);

    cout << "myvector contains:";
    for(int i=0; i<myvector.size(); i++)
        cout << ' ' << myvector[i];
    cout << '\n';
}

返回:

myvector contains: 1 2 3 4 5 100 100 100 0 0 0 0

 

16)empty

bool empty() const noexcept;

測試向量是否爲空
返回該向量是否爲空(即其大小是否爲0)。

此函數不以任何方式修改容器。若要清除向量的內容,請參見vector::clear

參數:None

返回值:

若是容器大小爲0,則爲true,不然爲false。

 

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector;
    int sum{0};
    for(int i =1; i<=10; i++) myvector.push_back(i);
    while(!myvector.empty()){
        sum += myvector.back();
        myvector.pop_back();
    }

    cout << "total: " << sum << endl;
    return 0;
}

返回:

total: 55

該示例將向量的內容初始化爲數字序列(從1到10)。而後,它逐個彈出元素,直到爲空,而後計算它們的和。

 

17)reserve

void reserve (size_type n);

請求更改容量capacity
要求向量容量至少可以包含n個元素。
若是n大於當前向量容量,該函數將致使容器從新分配其存儲,從而將其容量增長到n(或更大)。
在全部其餘狀況下,函數調用不會致使從新分配,向量容量也不會受到影響。
這個函數對向量大小沒有影響,也不能改變它的元素

參數:

n:

向量的最小容量。
注意,獲得的向量容量可能等於或大於n。
成員類型size_type是無符號整數類型。

返回值:

none

若是請求的大小大於最大大小(vector::max_size),則拋出一個length_error異常。

若是是從新分配,則使用容器的分配器分配存儲,這可能會在失敗時拋出異常(對於默認分配器,若是分配請求沒有成功,則拋出bad_alloc)。

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int>::size_type sz;
    vector<int> foo;
    sz = foo.capacity();
    cout << "making foo grow: \n";
    for(int i=0; i<100; i++){
        foo.push_back(i);
        if(sz!=foo.capacity()){
            sz = foo.capacity();
            cout << "capacity changed : " << sz << endl;
        }
    }

    vector<int> bar;
    sz = bar.capacity();
    cout << sz <<endl; //0
    bar.reserve(100);
    cout << "making bar grow: \n";
    for(int i=0; i<100; i++){
        bar.push_back(i);
        if(sz!=bar.capacity()){
            sz = bar.capacity(); //直接爲100
            cout << "capacity changed: " << sz << endl;
        }
    }
    return 0;
}

返回:

making foo grow: 
capacity changed : 1
capacity changed : 2
capacity changed : 4
capacity changed : 8
capacity changed : 16
capacity changed : 32
capacity changed : 64
capacity changed : 128
0
making bar grow: 
capacity changed: 100

 

18)shrink_to_fit

void shrink_to_fit();

縮小以適應
請求容器減小容量以適應其大小。
該請求是非綁定的,容器實現能夠自由地進行優化,使向量的容量大於其大小。

這可能會致使從新分配,但對向量大小沒有影響,也不能改變其元素。

參數:

none

返回值:

none

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector(100);
    cout << "1.capacity of myvector: " << myvector.capacity() << endl;

    myvector.resize(10);
    cout << "2.capacity of myvector: " << myvector.capacity() << endl;

    myvector.shrink_to_fit();
    cout << "3.capacity of myvector: " << myvector.capacity() << endl;
    return 0;
}

返回:

1.capacity of myvector: 100
2.capacity of myvector: 100
3.capacity of myvector: 10

 

元素訪問

19)operator[]-不檢查是否出界

     reference operator[] (size_type n);
const_reference operator[] (size_type n) const;

訪問元素
返回指向向量容器中位置爲n的元素的引用。
相似的成員函數vector::at與這個操做符函數具備相同的行爲,但vector::at是有界檢查的,若是請求的位置超出範圍,則經過拋出out_of_range異常發出信號。

可移植程序不該該使用超出範圍的參數n來調用這個函數,由於這會致使未定義的行爲。

參數:

n:

元素在容器中的位置。
注意,第一個元素的位置是0(不是1)。
成員類型size_type是無符號整數類型。

返回值:

在向量中指定位置的元素。
若是vector對象是const限定的,則該函數返回一個const_reference。不然,它返回一個引用。
成員類型reference和const_reference是容器元素的引用類型(請參閱向量成員類型)。

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector(10);
    vector<int>::size_type sz = myvector.size();

    //賦值
    for(unsigned i = 0; i<sz; i++) myvector[i] = i;

    //調換順序
    for(unsigned i = 0; i<sz/2; i++){
        int temp;
        temp = myvector[sz-1-i];
        myvector[sz-1-i] = myvector[i];
        myvector[i] = temp;
    }
    cout << "myvector contains: ";
    for(unsigned i=0; i<sz; i++)
        cout << ' ' << myvector[i];
    cout << endl;
    return 0;
}

返回:

myvector contains:  9 8 7 6 5 4 3 2 1 0

 

20)at - 檢查是否出界

      reference at (size_type n);
const_reference at (size_type n) const;

訪問元素
返回指向向量中位置爲n的元素的引用。

該函數自動檢查n是否在向量中有效元素的範圍內,若是不是,則拋出out_of_range異常(即,若是n大於或等於它的大小)。這與成員操做符[]造成對比,後者不檢查界限。

參數:

n:

元素在容器中的位置。
若是該值大於或等於向量大小,則拋出out_of_range類型的異常。
注意,第一個元素的位置是0(不是1)。
成員類型size_type是無符號整數類型。

返回值:

在容器中指定位置的元素。
若是vector對象是const限定的,則該函數返回一個const_reference。不然,它返回一個引用。
成員類型reference和const_reference是容器元素的引用類型(請參閱向量成員類型)。

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector(10);

    //賦值
    for(unsigned i= 0; i<myvector.size(); i++)
        myvector.at(i) = i;
    
    cout << "myvector contains : ";
    for(unsigned i =0; i<myvector.size(); i++)
        cout << ' ' << myvector.at(i);
    cout << endl;
    return 0;
}

返回:

myvector contains :  0 1 2 3 4 5 6 7 8 9

 

21)front

      reference front();
const_reference front() const;

訪問第一個元素
返回對向量中第一個元素的引用。
與成員vector::begin(它將迭代器返回到相同的元素)不一樣,此函數將返回一個直接引用

在空容器上調用此函數將致使未定義的行爲。

參數:

none

返回值:

指向向量容器中的第一個元素的引用。
若是vector對象是const限定的,則該函數返回一個const_reference。不然,它返回一個引用。
成員類型reference和const_reference是容器元素的引用類型(請參閱向量成員類型)。

 

22)back

      reference back();
const_reference back() const;

訪問的最後一個元素
返回對向量中最後一個元素的引用。
與成員vector::end返回的迭代器恰好通過這個元素不一樣,這個函數返回一個直接引用。
在空容器上調用此函數將致使未定義的行爲。

參數:

none

返回值:

指向向量中最後一個元素的引用。
若是vector對象是const限定的,則該函數返回一個const_reference。不然,它返回一個引用。
成員類型reference和const_reference是向量元素的引用類型(參見成員類型)。

 

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector;

    myvector.push_back(78); //front的值
    myvector.push_back(16); //back的值

    cout << "myvector.front() is now " << myvector.front() << endl;
    cout << "myvector.back() is now " << myvector.back() << endl;
    myvector.front() -= myvector.back();

    cout << "myvector.front() is now " << myvector.front() << endl;
    cout << "myvector.back() is now " << myvector.back() << endl;

    return 0;
}

返回:

myvector.front() is now 78
myvector.back() is now 16
myvector.front() is now 62
myvector.back() is now 16

 

23)data

      value_type* data() noexcept;
const value_type* data() const noexcept;

訪問數據
返回指向向量內部用於存儲其擁有的元素的內存數組的直接指針。

因爲保證向量中的元素以向量表示的相同順序存儲在連續的存儲位置中,所以能夠偏移檢索到的指針以訪問數組中的任何元素。

參數:

none

返回值:

指向向量內部使用的數組中的第一個元素的指針。
若是vector對象是const限定的,該函數將返回一個指向const value_type的指針。不然,它返回一個value_type指針。
成員類型value_type是容器中元素的類型,在vector中定義爲第一個類模板參數(T)的別名。

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector(5);

    int* p = myvector.data();
    *p = 10; //第一個元素賦值爲10
    ++p;
    *p = 20; //第二個賦值爲20
    //p[0]從myvector[1]開始
    cout << p[0] << '\t'<< p[1] << '\t'<< p[2] << '\t'<< p[3] << '\t'<< p[4] << endl;
    p[2] = 100;
    cout << "myvector contains:";
    for(unsigned i=0; i<myvector.size(); ++i)
        cout << ' ' << myvector[i];
    cout << endl;
    return 0;
}

返回:

20    0    0    0    32644
myvector contains: 10 20 0 100 0

 

修改:

24)assign

range (1)    
template <class InputIterator>
  void assign (InputIterator first, InputIterator last);

fill (
2) void assign (size_type n, const value_type& val);
initializer list (
3) void assign (initializer_list<value_type> il);

分配向量內容
將新內容分配給向量,替換其當前內容,並相應地修改其大小。

解釋:

在range版本(1)中,新內容是由first和last之間的每一個元素按照相同的順序構造的元素。
在fill版本(2)中,新內容是n個元素,每一個元素初始化爲val的一個副本。
在初始化列表版本(3)中,新內容是做爲初始化列表傳遞的值的副本,順序相同。
若是發生了從新分配,則使用內部分配器(經過其特性)來分配和釋放存儲。它也被用來破壞全部現有的元素,並構建新的元素。

 

在調用以前容器中保存的任何元素都將被銷燬,並由新構造的元素替換(不進行元素分配)。
當且僅當新向量大小超過當前向量容量時,這將致使分配的存儲空間的自動從新分配。

參數:

first, last:

將迭代器輸入到範圍的初始和最終位置。使用的範圍是[first,last),它包括first和last之間的全部元素,包括first指向的元素,但不包括last指向的元素。
函數模板參數InputIterator應該是一個輸入迭代器類型,它指向能夠構造value_type對象的類型的元素。

n:

初始容器大小(即,在構造時容器中的元素數)。
成員類型size_type是無符號整數類型。

val:

要填充容器的值。容器中的n個元素都將被初始化爲該值的一個副本。
成員類型value_type是容器中元素的類型,在vector中定義爲其第一個模板參數(T)的別名。

 il:

一個initializer_list對象。
這些對象是由初始化器列表聲明器自動構造的。
成員類型value_type是容器中元素的類型,在vector中定義爲其第一個模板參數(T)的別名。

返回值:

none

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> first;
    vector<int> second;
    vector<int> third;

    first.assign(7,100); //7個值爲100
    vector<int>::iterator it;
    it = first.begin()+1;

    second.assign(it, first.end()-1); //first[1:6]的5個值

    int myints[] = {1776, 7, 4};
    third.assign(myints, myints+3); //從數組中賦值
    cout << "size of first : " << int(first.size()) << endl;
    cout << "size of second : " << int(second.size()) << endl;
    cout << "size of third : " << int(third.size()) << endl;
    return 0;
}

返回:

size of first : 7
size of second : 5
size of third : 3

 

25)push_back

void push_back (const value_type& val);
void push_back (value_type&& val);

在末尾添加元素
在向量的最後一個元素以後添加一個新元素。val的內容被複制(或移動)到新元素。
這有效地將容器大小增長了1,當且僅當新向量大小超過當前向量容量時,就會自動從新分配分配的存儲空間。

參數:

val:

要複製(或移動)到新元素的值。
成員類型value_type是容器中元素的類型,在vector中定義爲其第一個模板參數(T)的別名。

返回值

none

若是發生了從新分配,則使用容器的分配器分配存儲,這可能會在失敗時拋出異常(對於默認分配器,若是分配請求沒有成功,則拋出bad_alloc)。

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector;
    int myint;

    cout << "Please enter some integers (enter 0 to end): \n";
    do{
        cin >> myint;
        myvector.push_back(myint);
    }while(myint);
    cout << "myvector stores " << int(myvector.size()) << " numbers.\n";
    return 0;
}

返回:

Please enter some integers (enter 0 to end): 
3
5
2
0
myvector stores 4 numbers.

該示例使用push_back在每次讀取新整數時向向量添加新元素。

 

26)pop_back

void pop_back();

刪除最後一個元素
刪除向量中的最後一個元素,有效地將容器大小減小了1。
這將破壞刪除的元素。

參數:

none

返回值:

none

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector;
    int sum(0);
    myvector.push_back(100);
    myvector.push_back(200);
    myvector.push_back(300);
    while(!myvector.empty()){
        sum += myvector.back();
        myvector.pop_back();
    }
    cout << "the elements of myvector add up to " << sum << endl;
    return 0;
}

返回:

the elements of myvector add up to 600

 

27)insert

single element (1)    
iterator insert (const_iterator position, const value_type& val);

fill (
2) iterator insert (const_iterator position, size_type n, const value_type& val);
range (
3) template <class InputIterator> iterator insert (const_iterator position, InputIterator first, InputIterator last);
move (
4) iterator insert (const_iterator position, value_type&& val);
initializer list (
5) iterator insert (const_iterator position, initializer_list<value_type> il);

插入元素
經過在元素以前插入指定位置的新元素來擴展向量,從而有效地經過插入的元素數量增長容器的大小。
當且僅當新向量大小超過當前向量容量時,這將致使分配的存儲空間的自動從新分配。

由於向量使用數組做爲它們的底層存儲,因此將元素插入到向量末端之外的位置會致使容器將全部在position以後的元素從新定位到它們的新位置。與其餘類型的序列容器(如list或forward_list)對同一操做執行的操做相比,這一般是一個低效的操做。

這些參數決定了插入了多少個元素,並將它們初始化爲哪些值:

參數:

position:

在向量中插入新元素的位置。
iterator是一個成員類型,定義爲一個指向元素的隨機訪問迭代器類型。

first, last:

將迭代器輸入到範圍的初始和最終位置。使用的範圍是[first,last),它包括first和last之間的全部元素,包括first指向的元素,但不包括last指向的元素。
函數模板參數InputIterator應該是一個輸入迭代器類型,它指向能夠構造value_type對象的類型的元素。

n:

初始容器大小(即,在構造時容器中的元素數)。
成員類型size_type是無符號整數類型。

val:

要填充容器的值。容器中的n個元素都將被初始化爲該值的一個副本。
成員類型value_type是容器中元素的類型,在vector中定義爲其第一個模板參數(T)的別名。

 il:

一個initializer_list對象。
這些對象是由初始化器列表聲明器自動構造的。
成員類型value_type是容器中元素的類型,在vector中定義爲其第一個模板參數(T)的別名。

 

返回值:

指向第一個新插入元素的迭代器。
成員類型迭代器是指向元素的隨機訪問迭代器類型。
若是發生從新分配,則使用容器的分配器分配存儲,這可能會在失敗時拋出異常(對於默認分配器,若是分配請求沒有成功,則拋出bad_alloc)。

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector(3,100);
    vector<int>::iterator it;

    it = myvector.begin();
    it = myvector.insert(it, 200); //前面加個200,此時it在200前面
    myvector.insert(it,2,300); //前面加2個300
    cout << "myvector contains : ";
    for(it = myvector.begin(); it<myvector.end(); it++)
        cout << ' ' << *it;
    cout << endl;

    //it再也不有效,從新得到
    it = myvector.begin();//此時it在300前面
    vector<int> anothervector(2, 400);
    //在300和200見加2個400
    myvector.insert(it+2, anothervector.begin(), anothervector.end());
    cout << "myvector contains : ";
    for(it = myvector.begin(); it<myvector.end(); it++)
        cout << ' ' << *it;
    cout << endl;
    
    int myarray[] = {501,502,503};
    myvector.insert(myvector.begin(), myarray, myarray+3);

    cout << "myvector contains : ";
    for(it = myvector.begin(); it<myvector.end(); it++)
        cout << ' ' << *it;
    cout << endl;
    return 0;
}

返回:

myvector contains :  300 300 200 100 100 100
myvector contains :  300 300 400 400 200 100 100 100
myvector contains :  501 502 503 300 300 400 400 200 100 100 100

 

28)erase

iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);

刪除元素
從向量中刪除單個元素(位置)或元素範圍([first,last])。

這有效地減小了容器的大小,減小了被刪除的元素的數量。
由於向量使用一個數組做爲它們的底層存儲,擦除向量端之外位置的元素會致使容器在擦除段以後將全部元素從新定位到它們的新位置。與其餘類型的序列容器(如list或forward_list)對同一操做執行的操做相比,這一般是一個低效的操做。

參數:

position:

在向量中插入新元素的位置。
iterator是一個成員類型,定義爲一個指向元素的隨機訪問迭代器類型。

first, last:

將迭代器輸入到範圍的初始和最終位置。使用的範圍是[first,last),它包括first和last之間的全部元素,包括first指向的元素,但不包括last指向的元素。
函數模板參數InputIterator應該是一個輸入迭代器類型,它指向能夠構造value_type對象的類型的元素。
返回值:
一個迭代器,指向函數調用 擦除的最後一個元素以後的元素的新位置。若是操做擦除序列中的最後一個元素,則返回容器端。
成員類型迭代器是指向元素的隨機訪問迭代器類型。

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector;
    //賦值
    for(int i=1; i<=10; i++) myvector.push_back(i);

    //擦除第6個元素
    myvector.erase(myvector.begin()+5);
    cout << "myvector contains : " ;
    for(unsigned i = 0; i<myvector.size(); ++i)
        cout << ' ' << myvector[i];
    cout << endl;
    
    //擦除前3個
    myvector.erase(myvector.begin(), myvector.begin()+3);

    cout << "myvector contains : " ;
    for(unsigned i = 0; i<myvector.size(); ++i)
        cout << ' ' << myvector[i];
    cout << endl;
    return 0;
}

返回:

myvector contains :  1 2 3 4 5 7 8 9 10
myvector contains :  4 5 7 8 9 10

 

29)swap

void swap (vector& x);

交換內容
經過x的內容交換容器的內容,x是另外一個相同類型的向量對象。大小可能不一樣。
在調用這個成員函數以後,這個容器中的元素是調用以前x中的元素,x中的元素是調用以前x中的元素。全部迭代器、引用和指針對交換後的對象仍然有效。
請注意,存在一個具備相同名稱的非成員函數,交換,用相似於這個成員函數的優化來重載該算法。

 容器分配器是否也交換沒有定義,除非在這種狀況下,適當的allocator traits(分配器特性)明確地指示它們應該傳播。

vector的bool爲這個函數提供了額外的重載(參見vector<bool>::swap)。

參數:

x:

另外一個相同類型的向量容器(即,用相同的模板參數T和Alloc實例化),其內容與此容器的內容交換。

返回值:

none

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> foo(3,100);
    vector<int> bar(5,200);
    cout << "foo contains: ";
    for(unsigned i=0; i<foo.size(); i++)
        cout << ' ' << foo[i];
    cout << endl;
    
    cout << "bar contains: ";
    for(unsigned i=0; i<bar.size(); i++)
        cout << ' ' << bar[i];
    cout << endl;

    foo.swap(bar);
    cout << "after swap foo contains: ";
    for(unsigned i=0; i<foo.size(); i++)
        cout << ' ' << foo[i];
    cout << endl;

    cout << "after swap bar contains: ";
    for(unsigned i=0; i<bar.size(); i++)
        cout << ' ' << bar[i];
    cout << endl;
    return 0;
}

返回:

foo contains:  100 100 100
bar contains:  200 200 200 200 200
after swap foo contains:  200 200 200 200 200
after swap bar contains:  100 100 100

 

30)clear

void clear() noexcept;

清除內容
刪除向量中的全部元素(已銷燬的元素),使容器的大小爲0。

不能保證會發生從新分配,也不能保證因爲調用此函數而改變向量容量。強制從新分配的典型替代方案是使用swap:

vector<T>().swap(x);   // clear x reallocating 

參數:

none

返回值:

none

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector;
    myvector.push_back(100);
    myvector.push_back(200);
    myvector.push_back(300);

    cout << "myvector contains : ";
    for(unsigned i =0; i<myvector.size(); i++)
        cout << ' ' << myvector[i];
    cout << endl;

    myvector.clear(); //清空
    myvector.push_back(1101);
    myvector.push_back(2202);

    cout << "myvector contains : ";
    for(unsigned i =0; i<myvector.size(); i++)
        cout << ' ' << myvector[i];
    cout << endl;
    return 0;
}

返回:

myvector contains :  100 200 300
myvector contains :  1101 2202

 

31) emplace - 一次插入一個

template <class... Args>
iterator emplace (const_iterator position, Args&&... args);

構造和插入元素
經過在位置插入新元素來擴展容器。這個新元素是使用args做爲構造參數在適當的地方構造的。

這有效地將容器大小增長了1
當且僅當新向量大小超過當前向量容量時,將自動從新分配分配的存儲空間。

由於向量使用數組做爲它們的底層存儲,因此將元素插入到向量末端之外的位置會致使容器將全部在position以後的元素移動到它們的新位置。與其餘類型的序列容器(如list或forward_list)執行的操做相比,這一般是一個低效的操做。請參閱emplace_back,瞭解在末尾直接擴展容器的成員函數。

元素是經過調用allocator_traits::construct和args轉發來就地構造的。
存在一個相似的成員函數insert,它複製或將現有對象移動到容器中。

參數:

position:

在向量中插入新元素的位置。
iterator是一個成員類型,定義爲一個指向元素的隨機訪問迭代器類型。

args:

用於構造新元素的參數。

返回值:

指向新放置元素的迭代器。
成員類型迭代器是指向元素的隨機訪問迭代器類型。
若是發生了從新分配,則使用容器的分配器分配存儲,這可能會在失敗時拋出異常(對於默認分配器,若是分配請求沒有成功,則拋出bad_alloc)。

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector = {10,20,30};
    auto it = myvector.emplace(myvector.begin()+1, 100);
    myvector.emplace(it, 200);
    myvector.emplace(myvector.end(), 300);

    cout << "myvector contains : ";
    for(auto& x : myvector)
        cout << ' ' << x;
    cout << endl;
    return 0;
}

返回:

myvector contains :  10 200 100 20 30 300

 

32)emplace_back - 在尾巴插入

template <class... Args>
  void emplace_back (Args&&... args);

構造並在末尾插入元素
在向量的末尾插入一個新元素,正好在它當前的最後一個元素以後。這個新元素是使用args做爲其構造函數的參數在適當的地方構造的。

這有效地將容器大小增長了1,當且僅當新向量大小超過當前向量容量時,就會自動從新分配分配的存儲空間。
元素是經過調用allocator_traits::construct和args轉發來就地構造的。
存在一個相似的成員函數push_back,它複製或將現有對象移動到容器中。

參數:

args:

用於構造新元素的參數。

返回值:

none

若是發生了從新分配,則使用容器的分配器分配存儲,這可能會在失敗時拋出異常(對於默認分配器,若是分配請求沒有成功,則拋出bad_alloc)。

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector = {10,20,30};
    myvector.emplace_back(100);
    myvector.emplace_back(200);

    cout << "myvector contains : ";
    for(auto& x : myvector)
        cout << ' ' << x;
    cout << endl;
    return 0;
}

返回:

myvector contains :  10 20 30 100 200

 

Allocator分配器:

33)get_allocator

allocator_type get_allocator() const noexcept;

獲得分配器
返回與向量關聯的分配器對象的副本。

參數:

none

返回值:

分配器

成員類型allocator_type是容器使用的分配器的類型,在vector中定義爲其第二個模板參數(Alloc)的別名。

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> myvector ;
    int* p;
    unsigned int i;

    //使用vector的分配器分配一個有着5個元素空間的數組
    p = myvector.get_allocator().allocate(5);

    //在數組中構建適當的值:
    for(i=0; i<5; i++) myvector.get_allocator().construct(&p[i], i);

    cout << "the allocated array contains :";
    for(i=0; i<5; i++) cout << ' ' << p[i];
    cout << endl;

    //銷燬和去分配
    for(i=0; i<5; i++) myvector.get_allocator().destroy(&p[i]);
    myvector.get_allocator().deallocate(p,5);
    return 0;
}

返回:

the allocated array contains : 0 1 2 3 4

 

至此都是public member function

 

下面是非成員函數重載:

34)relational operators (vector)

(1)    
template <class T, class Alloc>
  bool operator== (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);

(2)    
template <class T, class Alloc>
  bool operator!= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);

(3)    
template <class T, class Alloc>
  bool operator<  (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);

(4)    
template <class T, class Alloc>
  bool operator<= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);

(5)    
template <class T, class Alloc>
  bool operator>  (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);

(6)    
template <class T, class Alloc>
  bool operator>= (const vector<T,Alloc>& lhs, const vector<T,Alloc>& rhs);

向量的操做符
在向量容器lhs和rhs之間執行適當的比較操做。

相等比較(運算符==)是經過首先比較大小來執行的,若是大小匹配,則使用運算符==對元素進行順序比較,在第一次不匹配時中止(就像使用算法equal同樣)。

less-than比較(操做符<)的行爲相似於使用lexicographical_compare算法,該算法以互惠的方式使用操做符<(即,檢查a<b和b<a),並在第一次出現時中止。

其餘操做也在內部使用操做符==和<來比較元素,其行爲相似於執行如下等價操做:

 

 

 這些操做符在頭文件<vector>中被重載

參數:

lhs, rhs:
向量容器(分別位於操做符的左側和右側),具備相同的模板參數(T和Alloc)。
返回值:
若是條件知足則返回true,不然爲false
舉例:
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> foo(3,100) ;
    vector<int> bar(2,200);

    if(foo == bar) cout << "foo and bar are equal\n";
    if(foo != bar)cout << "foo and bar are not equal\n";
    if(foo < bar) cout << "foo is less than bar\n";
    if(foo > bar) cout << "foo is greater than bar\n";
    if(foo <= bar) cout << "foo is less than or equal to bar\n";
    if(foo >= bar) cout << "foo is greater than or equal to bar\n";

    return 0;
}

返回:

foo and bar are not equal
foo is less than bar
foo is less than or equal to bar

 

35)swap

template <class T, class Alloc>
  void swap (vector<T,Alloc>& x, vector<T,Alloc>& y);

交換向量內容
容器x的內容與容器y的內容交換。兩個容器對象必須具備相同的類型(相同的模板參數),儘管大小可能不一樣

調用這個成員函數後,x中的元素是調用以前在y中的元素,y中的元素是在x中的元素。全部迭代器、引用和指針對交換後的對象仍然有效。

這是泛型算法交換的一個重載,它經過將資產的全部權相互轉移到另外一個容器來提升性能(例如,,容器交換對其數據的引用,而不實際執行任何元素複製或移動):它的行爲就像調用了x.swap(y)

參數:

x,y:

相同類型的向量容器(即,具備相同的模板參數T和Alloc)。

返回值:

none

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    unsigned int i;
    std::vector<int> foo (3,100);   // three ints with a value of 100
    std::vector<int> bar (5,200);   // five ints with a value of 200
    std::cout << "foo contains:";
    for (std::vector<int>::iterator it = foo.begin(); it!=foo.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    std::cout << "bar contains:";
    for (std::vector<int>::iterator it = bar.begin(); it!=bar.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    swap(foo, bar);

    std::cout << "after swap foo contains:";
    for (std::vector<int>::iterator it = foo.begin(); it!=foo.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    std::cout << "after swap bar contains:";
    for (std::vector<int>::iterator it = bar.begin(); it!=bar.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';
    return 0;
}

返回:

foo contains: 100 100 100
bar contains: 200 200 200 200 200
after swap foo contains: 200 200 200 200 200
after swap bar contains: 100 100 100

 

Template specializations模版特殊化

36)vector<bool>

template < class T, class Alloc = allocator<T> > class vector; // generic template
template <class Alloc> class vector<bool,Alloc>;               // bool specialization

bool矢量
這是vector的一個特殊版本,用於bool類型的元素並對空間進行優化。

它的行爲就像矢量的非特殊化版本,有如下變化:

  • 存儲不必定是bool值的數組,可是庫實現能夠優化存儲,使每一個值都存儲在單個bit位中。
  • 元素不是使用分配器對象構造的,可是它們的值直接設置在內部存儲的適當位上。
  • 成員函數翻轉flip和用於成員交換swap的新簽名。
  • 一個特殊的成員類型,引用,一個類,它使用一個模擬bool引用的接口來訪問容器內部存儲中的各個位。相反,成員類型const_reference是普通的bool。
  • 容器使用的指針和迭代器類型不必定既不是指針也不是符合條件的迭代器,儘管它們應該模擬大多數預期的行爲。

這些變化爲這種特殊化提供了一個古怪的接口,而且更傾向於內存優化而不是處理(這可能適合也可能不適合您的須要)。在任何狀況下,都不可能直接爲bool實例化vector的未特殊化模板。避免使用不一樣類型(char、unsigned char)或容器(如deque)來使用包裝器類型或進一步特殊化特定的分配器類型,從而避免這種狀況。
bitset是一個爲固定大小的位數組提供相似功能的類。

模版參數:

Alloc:

用於定義存儲分配模型的分配器對象的類型。默認狀況下,使用的是allocate<bool>,它定義了最簡單的內存分配模型,而且是與值無關的。
別名爲成員類型vector<bool>::allocator_type。

 

成員類型

跟特殊的差很少:

成員類型  定義  notes
value_type 第一個模版參數boool  
allocator_type 第二個模版參數Alloc 默認爲allocator<bool>
reference 一個特殊成員類  
const_reference bool  
pointer 模擬指向行爲的指針的類型 可轉換成const_pointer
const_pointer 模擬指向const行爲的指針的類型  
iterator 模擬隨機訪問迭代器迭代行爲的類型 可轉換成const_iterator
const_iterator 模擬隨機訪問迭代器迭代到const行爲的類型  
reverse_iterator reverse_iterator<iterator>  
const_reverse_iterator reverse_iterator<const_iterator>  
difference_type 一種有符號整數類型 一般是ptrdiff_t
size_type   一般是size_t

 

 

 

 

 

 

 

 

 

 

成員類:

1》 vector<bool>::reference

class reference;

引用類型
這個嵌入的類是由很是量vector<bool>的成員在直接訪問它的元素時返回的類型。它使用一個模擬對bool引用的接口來訪問各個位。

其原型爲:

class vector<bool>::reference {
  friend class vector;
  reference() noexcept;                                 // no public constructor
public:
  ~reference();
  operator bool () const noexcept;                      // convert to bool
  reference& operator= (const bool x) noexcept;         // assign from bool
  reference& operator= (const reference& x) noexcept;   // assign from bit
  void flip();                                          // flip bit value.
};

 

成員函數:

特殊化具備與非特殊化向量相同的成員函數,但data、emplace和emplace_back函數不在此特殊化中。

同時還添加了下面的兩個函數:

1》flip

void flip() noexcept;

翻轉位
將容器中的全部值翻轉:全部true實例變爲false,全部false實例變爲true。

參數:

none

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<bool> mask;
    mask.push_back(true);
    mask.push_back(false);
    mask.push_back(false);
    mask.push_back(true);

    mask.flip();

    cout << boolalpha; //讓返回值是true/false形式,而不是0/1
    cout << "mask contains : ";
    for(unsigned i=0; i<mask.size(); i++)
        cout << ' ' << mask.at(i);
    cout << endl;
    return 0;
}

返回:

mask contains :  false true true false

 

2》swap

swap containers (1)    
void swap (vector& x);
swap elements (
2) static void swap (reference ref1, reference ref2) noexcept;

交換容器或元素
第一個簽名與vector::swap中描述的相同(更多信息請參見vector::swap)。
在vector<bool>上添加一個用於交換單個元素(位)的靜態簽名

參數:

x:

另外一個vector<bool>容器。大小可能不一樣

ref1,ref2:

對元素的引用。
reference是一種成員類型,它訪問各個元素,同時提供一個模擬bool引用的接口(有關更多信息,請參閱reference)。

返回值:

none

舉例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<bool> foo;
    vector<bool> bar;

    foo.push_back(false);
    foo.push_back(true);
    foo.push_back(false);

    bar.push_back(true);
    bar.push_back(false);

    //交換元素
    foo.swap(foo[0], foo[1]);
    bar.swap(bar.front(), bar.back());
    
    cout << boolalpha; //讓返回值是true/false形式,而不是0/1
    cout << "foo contains : ";
    for(unsigned i=0; i<foo.size(); i++)
        cout << ' ' << foo.at(i);
    cout << endl;
    cout << "bar contains : ";
    for(unsigned i=0; i<bar.size(); i++)
        cout << ' ' << bar.at(i);
    cout << endl;

    //交換容器
    foo.swap(bar);

    cout << boolalpha; //讓返回值是true/false形式,而不是0/1
    cout << "foo contains : ";
    for(unsigned i=0; i<foo.size(); i++)
        cout << ' ' << foo.at(i);
    cout << endl;
    cout << "bar contains : ";
    for(unsigned i=0; i<bar.size(); i++)
        cout << ' ' << bar.at(i);
    cout << endl;

    return 0;
}

返回:

foo contains :  true false false
bar contains :  false true
foo contains :  false true
bar contains :  true false false

 

Non-member class specializations

1》hash<vector<bool>>

template <class T> struct hash;                             // unspecialized
template <class Alloc> struct hash <vector<bool,Alloc>>;    // vector<bool>

向量的散列向量
一元函數對象類,它定義了vector<bool>的hash特殊化。

函數調用返回一個基於整個向量的散列值:散列值是一個僅依賴於其參數的值,對於相同的參數(對於給定的程序執行)老是返回相同的值。返回的值與另外一個參數返回的值有很小的可能相同(碰撞的概率接近1/numeric_limits<size_t>::max)。
這容許使用vector<bool>對象做爲無序容器(如unordered_set或unordered_map)的鍵

有關其餘信息,請參見散列 hash

 

成員函數:

operator()

返回其參數的散列值,做爲類型size_t的值。size_t是一個無符號整數類型。

相關文章
相關標籤/搜索