C++ vector的使用


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

 

std::vector (C++11)

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

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

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

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

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

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

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

 

Container properties屬性

Sequence序列

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

Dynamic array動態數組

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

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是一個無符號整數類型。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM