C++ STL標(biāo)準(zhǔn)庫:std::vector 使用詳解

文章目錄

  1. 簡介
  2. 使用示例
  3. 構(gòu)造傀广、析構(gòu)杖刷、賦值
    3.1 std::vector::vector 構(gòu)造函數(shù)
    3.2 std::vector::~vector 析構(gòu)函數(shù)
    3.3 std::vector::operator= “=”符號
  4. Iterators 迭代器
    4.1 std::vector::begin
    4.2 std::vector::end
    4.3 std::vector::rbegin
    4.4 std::vector::rend
    4.5 std::vector::cbegin (C++11)
    4.6 std::vector::cend(C++11)
    4.7 std::vector::crbegin (C++11)
    4.8 std::vector::crend(C++11)
  5. Capacity 容量
    5.1 std::vector::size 查詢大小
    5.2 std::vector::max_size
    5.3 std::vector::resize
    5.4 std::vector::capacity
    5.5 std::vector::empty
    5.6 std::vector::reserve
    5.7 std::vector::shrink_to_fit (C++11)
  6. Element access 元素訪問
    6.1 std::vector::operator[]
    6.2 std::vector::at
    6.3 std::vector::front
    6.4 std::vector::back
    6.5 std::vector::data (C++11)
  7. Modifiers 內(nèi)容修改
    7.1 std::vector::assign
    7.2 std::vector::push_back
    7.3 std::vector::pop_back
    7.4 std::vector::insert
    7.5 std::vector::erase
    7.6 std::vector::swap
    7.7 std::vector::clear
    7.8 std::vector::emplace(C++11)
    7.9 std::vector::emplace_back (C++11)
  8. 簡介
    vector 是表示可以改變大小的數(shù)組的序列容器薄声。

與arrays一樣婉称,vector 對元素使用連續(xù)的存儲位置坟冲,這意味著也可以使用指向其元素的常規(guī)指針上的偏移量來訪問它們的元素舞箍,并且與在數(shù)組中一樣高效靠汁。但是與arrays不同蜂大,它們的大小可以動態(tài)變化闽铐,容器會自動處理它們的存儲。

在內(nèi)部奶浦,vector 使用一個動態(tài)分配的數(shù)組來存儲它們的元素兄墅。這個數(shù)組可能需要重新分配,以便在插入新元素時增大大小澳叉,這意味著分配一個新數(shù)組并將所有元素移動到其中隙咸。就處理時間而言,這是一項相對昂貴的任務(wù)成洗,因此五督,vector 不會在每次向容器添加元素時重新分配。

相反瓶殃,vector 容器可以分配一些額外的存儲空間以適應(yīng)可能的增長充包,因此容器的實際容量可能大于嚴(yán)格需要的存儲容量(即容器的大小)遥椿。庫可以實現(xiàn)不同的增長策略基矮,以平衡內(nèi)存使用和重新分配,但在任何情況下冠场,重新分配只應(yīng)在大小的對數(shù)增長間隔進行家浇,以便在向量末尾插入單個元素可以提供攤余的恒定時間復(fù)雜度(請參閱“推后”)。

因此慈鸠,與arrays相比蓝谨,vector 消耗更多的內(nèi)存,以換取管理存儲和以高效方式動態(tài)增長的能力青团。

與其他動態(tài)序列容器(deques譬巫、list和forward_list)相比,vectors可以非常高效地訪問其元素(就像數(shù)組一樣)督笆,并相對高效地從其末尾添加或刪除元素芦昔。對于涉及在結(jié)尾以外的位置插入或刪除元素的操作,它們的性能比其他操作差娃肿,迭代器和引用的一致性也不如列表和轉(zhuǎn)發(fā)列表咕缎。

  1. 使用示例
#include <iostream>
#include <string>
#include <vector>

using namespace std;

void main()
{
    
    vector<string>myvt;     // 定義模板類對象
    myvt.reserve(4);        // 設(shè)置大小
    cout << "The size is 4." << endl;

    // 添加內(nèi)容
    myvt.push_back("1. Beijing City.");
    myvt.push_back("2. Tianjin City.");
    myvt.push_back("3. Shanghai City.");
    myvt.push_back("4. Chongqing City.");

    // 打印內(nèi)容
    vector<string>::iterator it;
    for(it=myvt.begin();it!=myvt.end();it++)
    {
        cout<<*it<<endl;
    }

    int m=myvt.size();          // 獲取大小
    int n=myvt.capacity();      // 獲取容量
    int m1=myvt.max_size();     // 獲取最大大小
    cout<<"vector:myvt, size is "<<m<<endl;
    cout<<"vector:myvt, capacity is "<<n<<endl;
    cout<<"vector:myvt, maxsize is "<<m1<<endl;

    myvt.resize(10);    //重設(shè)大小
    cout<<"resize: 10."<<endl;
    int n1=myvt.capacity();
    int n2=myvt.size();
    cout<<"vector:myvt, capacity is "<<n1<<endl;
    cout<<"vector:myvt, size is "<<n2<<endl;

    // 如果為空值則打印 * 號
    for(it=myvt.begin();it!=myvt.end();it++)
    {
        if(*it=="")
            cout<<"******"<<endl;
        cout<<*it<<endl;
    }
    cin.get();
}
  1. 構(gòu)造、析構(gòu)料扰、賦值

3.1 std::vector::vector 構(gòu)造函數(shù)

(1) 空容器構(gòu)造函數(shù)
(默認(rèn)構(gòu)造函數(shù))構(gòu)造一個沒有元素的空容器凭豪。

(2) 填充構(gòu)造函數(shù)
用n個元素構(gòu)造一個容器。每個元素都是val的副本(如果提供)晒杈。

(3) 范圍構(gòu)造函數(shù)
構(gòu)造一個包含與range[first嫂伞,last]一樣多的元素的容器,每個元素的emplace都是按照相同的順序從該范圍中的相應(yīng)元素構(gòu)造的。

(4) 復(fù)制構(gòu)造函數(shù)(并使用分配器復(fù)制)
以相同的順序構(gòu)造一個容器帖努,其中包含x中每個元素的副本撰豺。

(5) 移動構(gòu)造函數(shù)(并使用分配器移動)
構(gòu)造一個獲取x元素的容器。
如果alloc被指定并且與x的分配器不同拼余,那么元素將被移動污桦。否則,就不會構(gòu)建任何元素(它們的所有權(quán)被直接轉(zhuǎn)移)匙监。
x處于未指定但有效的狀態(tài)凡橱。

(6) 初始化列表構(gòu)造
以相同的順序構(gòu)造一個容器,其中包含il中每個元素的副本舅柜。

// 構(gòu)造 vectors
#include <iostream>
#include <vector>

int main ()
{
  // 按上述順序使用的構(gòu)造函數(shù):
  std::vector<int> first;                                // 整數(shù)的空向量
  std::vector<int> second (4,100);                       // 值為100的四個整數(shù)
  std::vector<int> third (second.begin(),second.end());  // 遍歷構(gòu)造
  std::vector<int> fourth (third);                       // 賦值構(gòu)造

  // 迭代器構(gòu)造函數(shù)也可用于從數(shù)組構(gòu)造:
  int myints[] = {16,2,77,29};
  std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );

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

  return 0;
}

3.2 std::vector::~vector 析構(gòu)函數(shù)

~vector();
Destroys the container object.

3.3 std::vector::operator= “=”符號

// vector assignment
#include <iostream>
#include <vector>

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

  bar = foo;                    // bar: 0 0 0
  foo = std::vector<int>();     // foo:

  std::cout << "Size of foo: " << int(foo.size()) << '\n';
  std::cout << "Size of bar: " << int(bar.size()) << '\n';
  return 0;
}
  1. Iterators 迭代器

4.1 std::vector::begin
返回指向容器中第一個元素的迭代器梭纹。

返回指向向量中第一個元素的迭代器躲惰。

注意致份,與member vector::front不同,member vector::front返回對第一個元素的引用础拨,該函數(shù)返回指向該元素的隨機訪問迭代器氮块。

如果容器為空,則返回的迭代器值不應(yīng)被取消引用诡宗。

4.2 std::vector::end
返回指向容器最后一個元素所在位置后一個位置的迭代器滔蝉,通常和 begin() 結(jié)合使用。

返回一個迭代器塔沃,該迭代器引用向量容器中過去的結(jié)束元素蝠引。

過去的結(jié)束元素是理論元素,它將跟隨向量中的最后一個元素蛀柴。它不指向任何元素螃概,因此不應(yīng)被取消引用。

由于標(biāo)準(zhǔn)庫的函數(shù)使用的范圍不包括其結(jié)束迭代器所指向的元素鸽疾,因此此函數(shù)通常與vector::begin結(jié)合使用吊洼,以指定一個包含容器中所有元素的范圍。

如果容器為空制肮,此函數(shù)將返回與vector::begin相同的值冒窍。

// vector::begin/end
#include <iostream>
#include <vector>

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

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

  return 0;
}

4.3 std::vector::rbegin
返回指向最后一個元素的迭代器。

返回指向向量中最后一個元素的反向迭代器(即它的反向開始)豺鼻。

反向迭代器向后迭代:增加它們會將它們移向容器的開頭综液。

rbegin指向成員端將指向的元素之前的元素。

注意儒飒,與member vector::back不同谬莹,member vector::back返回對同一元素的引用,此函數(shù)返回反向隨機訪問迭代器。

4.4 std::vector::rend
返回指向第一個元素所在位置前一個位置的迭代器届良。

返回一個反向迭代器笆凌,該迭代器指向向量中第一個元素之前的理論元素(該元素被視為其反向末端)。
vector::rbegin和vector::rend之間的范圍包含向量的所有元素(按相反的順序)士葫。

// vector::rbegin/rend
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> myvector(5);  // 5個默認(rèn)構(gòu)造整數(shù)

    int i = 0;

    std::vector<int>::reverse_iterator rit = myvector.rbegin();
    for (; rit != myvector.rend(); ++rit)
        *rit = ++i;

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

    return 0;
}

4.5 std::vector::cbegin (C++11)
和 begin() 功能相同乞而,只不過在其基礎(chǔ)上,增加了 const 屬性慢显,不能用于修改元素爪模。

const_iterator cbegin() const noexcept;

返回指向容器中第一個元素的常量迭代器。

const_iterator是指向const內(nèi)容的迭代器荚藻。這個迭代器可以增加和減少(除非它本身也是const)屋灌,就像vector::begin返回的迭代器一樣,但是它不能用來修改它指向的內(nèi)容应狱,即使vector對象本身不是const共郭。

如果容器為空,則返回的迭代器值不應(yīng)被取消引用疾呻。

4.6 std::vector::cend(C++11)
和 end() 功能相同除嘹,只不過在其基礎(chǔ)上,增加了 const 屬性岸蜗,不能用于修改元素尉咕。

const_iterator cend() const noexcept;

返回一個指向容器中結(jié)束元素的常量迭代器。

const_iterator是指向const內(nèi)容的迭代器璃岳。這個迭代器可以增加和減少(除非它本身也是const)年缎,就像vector::end返回的迭代器一樣,但是它不能用來修改它指向的內(nèi)容铃慷,即使vector對象本身不是const单芜。

如果容器為空,此函數(shù)將返回與vector::cbegin相同的值枚冗。

返回的值不應(yīng)被取消引用缓溅。

// vector::cbegin/cend
#include <iostream>
#include <vector>

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

  std::cout << "myvector contains:";

  for (auto it = myvector.cbegin(); it != myvector.cend(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

4.7 std::vector::crbegin (C++11)
和 rbegin() 功能相同,只不過在其基礎(chǔ)上赁温,增加了 const 屬性坛怪,不能用于修改元素。

const_reverse_iterator crbegin() const noexcept;

返回一個const_reverse_迭代器股囊,指向容器中的最后一個元素(即它的反向開始)袜匿。

4.8 std::vector::crend(C++11)
和 rend() 功能相同,只不過在其基礎(chǔ)上稚疹,增加了 const 屬性居灯,不能用于修改元素祭务。

const_reverse_iterator crend() const noexcept;

返回一個const_reverse_迭代器,該迭代器指向容器中第一個元素之前的理論元素(該元素被視為其反向端)怪嫌。

// vector::crbegin/crend
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector = {1,2,3,4,5};

  std::cout << "myvector backwards:";
  for (auto rit = myvector.crbegin(); rit != myvector.crend(); ++rit)
    std::cout << ' ' << *rit;
  std::cout << '\n';

  return 0;
}
  1. Capacity 容量

5.1 std::vector::size 查詢大小
返回實際元素個數(shù)义锥。

size_type size() const noexcept;

返回矢量中的元素數(shù)。
這是向量中保存的實際對象的數(shù)量岩灭,它不一定等于它的存儲容量拌倍。

// vector::size
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myints;
  std::cout << "0. size: " << myints.size() << '\n';

  for (int i=0; i<10; i++) myints.push_back(i);
  std::cout << "1. size: " << myints.size() << '\n';

  myints.insert (myints.end(),10,100);
  std::cout << "2. size: " << myints.size() << '\n';

  myints.pop_back();
  std::cout << "3. size: " << myints.size() << '\n';

  return 0;
}

5.2 std::vector::max_size
返回元素個數(shù)的最大值。這通常是一個很大的值噪径,一般是 232-1柱恤,所以我們很少會用到這個函數(shù)。

size_type max_size() const noexcept;

返回向量可以容納的最大元素數(shù)找爱。
這是由于已知的系統(tǒng)或庫實現(xiàn)限制梗顺,容器可以達到的最大潛在大小,但容器決不能保證能夠達到該大谐瞪恪:在達到該大小之前寺谤,它仍然可能無法在任何時候分配存儲。

// comparing size, capacity and max_size
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> myvector;

    // 向myvector中添加內(nèi)容
    for (int i = 0; i < 100; i++) myvector.push_back(i);

    std::cout << "size: " << myvector.size() << "\n";
    std::cout << "capacity: " << myvector.capacity() << "\n";
    std::cout << "max_size: " << myvector.max_size() << "\n";
    return 0;
}

5.3 std::vector::resize
改變實際元素的個數(shù)练般。

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

調(diào)整容器大小矗漾,使其包含n個元素。
如果n小于當(dāng)前容器的大小薄料,則內(nèi)容將縮減為其前n個元素,移除超出的元素(并銷毀它們)泵琳。
如果n大于當(dāng)前容器大小摄职,則通過在末尾插入足夠多的元素來擴展內(nèi)容,以達到n的大小获列。如果指定了val谷市,則將新元素初始化為val的副本,否則击孩,它們將被值初始化迫悠。
如果n也大于當(dāng)前容器容量,則自動重新分配已分配的存儲空間巩梢。
請注意创泄,此函數(shù)通過插入或刪除容器中的元素來更改容器的實際內(nèi)容。

// resizing vector
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> myvector;

    // 初始化內(nèi)容
    for (int i = 1; i < 10; i++) myvector.push_back(i);

    myvector.resize(5);
    myvector.resize(8, 100);
    myvector.resize(12);

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

    return 0;
}

5.4 std::vector::capacity
返回當(dāng)前容量括蝠。

size_type capacity() const noexcept;

返回當(dāng)前為向量分配的存儲空間的大小鞠抑,以元素表示。
這個容量不一定等于向量大小忌警。它可以相等或更大搁拙,額外的空間可以適應(yīng)增長,而不需要在每次插入時重新分配。
請注意箕速,此容量不假定對向量大小有限制酪碘。當(dāng)這個容量耗盡并且需要更多容量時,容器會自動擴展它(重新分配它的存儲空間)盐茎。向量大小的理論限制由成員max_size給出婆跑。
可以通過調(diào)用成員vector::reserve顯式更改向量的容量。

// comparing size, capacity and max_size
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;

  // set some content in the vector:
  for (int i=0; i<100; i++) myvector.push_back(i);

  std::cout << "size: " << (int) myvector.size() << '\n';
  std::cout << "capacity: " << (int) myvector.capacity() << '\n';
  std::cout << "max_size: " << (int) myvector.max_size() << '\n';
  return 0;
}

5.5 std::vector::empty
** 判斷容器中是否有元素庭呜,若無元素滑进,則返回 true;反之募谎,返回 false扶关。**

bool empty() const noexcept;

返回向量是否為空(即其大小是否為0)。
此函數(shù)不會以任何方式修改容器数冬。若要清除向量的內(nèi)容节槐,請參見vector::clear。

// vector::empty
#include <iostream>
#include <vector>

int main ()
{
  std::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();
  }

  std::cout << "total: " << sum << '\n';

  return 0;
}

5.6 std::vector::reserve
增加容器的容量拐纱。

void reserve (size_type n);

要求向量容量至少足以包含n個元素铜异。
如果n大于當(dāng)前向量容量,函數(shù)將使容器重新分配其存儲空間秸架,將其容量增加到n(或更大)揍庄。
在所有其他情況下,函數(shù)調(diào)用不會導(dǎo)致重新分配东抹,向量容量也不會受到影響蚂子。
此函數(shù)對向量大小沒有影響,并且不能更改其元素缭黔。

// vector::reserve
#include <iostream>
#include <vector>

int main()
{
    std::vector<int>::size_type sz;

    std::vector<int> foo;
    sz = foo.capacity();
    std::cout << "making foo grow:\n";
    for (int i = 0; i < 100; ++i) {
        foo.push_back(i);
        if (sz != foo.capacity()) {
            sz = foo.capacity();
            std::cout << "容量已更改: " << sz << '\n';
        }
    }

    std::vector<int> bar;
    sz = bar.capacity();
    bar.reserve(100);   // 這是與上面的foo唯一的區(qū)別
    std::cout << "making bar grow:\n";
    for (int i = 0; i < 100; ++i) {
        bar.push_back(i);
        if (sz != bar.capacity()) {
            sz = bar.capacity();
            std::cout << "容量已更改: " << sz << '\n';
        }
    }
    return 0;
}

5.7 std::vector::shrink_to_fit (C++11)
將內(nèi)存減少到等于當(dāng)前元素實際所使用的大小食茎。

void shrink_to_fit();

請求容器減小其容量以適合其大小。
請求是非綁定的馏谨,容器實現(xiàn)可以自由地進行優(yōu)化别渔,使向量的容量大于其大小。
這可能會導(dǎo)致重新分配惧互,但對向量大小沒有影響哎媚,并且無法更改其元素。

// vector::shrink_to_fit
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> myvector(100);
    std::cout << "1. myvector的容量: " << myvector.capacity() << '\n';

    myvector.resize(10);
    std::cout << "2. myvector的容量: " << myvector.capacity() << '\n';

    myvector.shrink_to_fit();
    std::cout << "3. myvector的容量: " << myvector.capacity() << '\n';

    return 0;
}
  1. Element access 元素訪問

6.1 std::vector::operator[]
重載了 [ ] 運算符壹哺,可以向訪問數(shù)組中元素那樣抄伍,通過下標(biāo)即可訪問甚至修改 vector 容器中的元素。

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

返回對向量容器中位置n處元素的引用管宵。
類似的成員函數(shù)vector :: at與該運算符具有相同的行為截珍,不同之處在于vector :: at已進行邊界檢查攀甚,并通過引發(fā)out_of_range異常來發(fā)出信號,以指示請求的位置是否超出范圍岗喉。
可移植程序永遠(yuǎn)不要使用參數(shù)n超出范圍來調(diào)用此函數(shù)秋度,因為這會導(dǎo)致未定義的行為。

// vector::operator[]
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> myvector(10);   // 10個零初始化元素

    std::vector<int>::size_type sz = myvector.size();

    // 分配一些值:
    for (unsigned i = 0; i < sz; i++) myvector[i] = i;

    // reverse vector using operator[]:
    for (unsigned i = 0; i < sz / 2; i++)
    {
        int temp;
        temp = myvector[sz - 1 - i];
        myvector[sz - 1 - i] = myvector[i];
        myvector[i] = temp;
    }

    std::cout << "myvector contains:";
    for (unsigned i = 0; i < sz; i++)
        std::cout << ' ' << myvector[i];
    std::cout << '\n';

    return 0;
}

6.2 std::vector::at
使用經(jīng)過邊界檢查的索引訪問元素钱床。

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

返回對向量中位置n處元素的引用荚斯。
該函數(shù)自動檢查n是否在向量中的有效元素的范圍內(nèi),如果不是查牌,則拋出out_of_range異常(即事期,如果n大于或等于其大小)纸颜。 這與成員operator []不同兽泣,后者不檢查邊界。

// vector::at
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> myvector(10);   // 10個零初始化的整數(shù)

    // 分配一些值:
    for (unsigned i = 0; i < myvector.size(); i++)
        myvector.at(i) = i;

    std::cout << "myvector contains:";
    for (unsigned i = 0; i < myvector.size(); i++)
        std::cout << ' ' << myvector.at(i);
    std::cout << '\n';

    return 0;
}

6.3 std::vector::front
返回第一個元素的引用胁孙。

      reference front();
const_reference front() const;

返回對向量中第一個元素的引用唠倦。
與成員vector :: begin返回一個迭代器到同一元素不同,此函數(shù)返回直接引用涮较。
在空容器上調(diào)用此函數(shù)會導(dǎo)致未定義的行為稠鼻。

// vector::front
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> myvector;

    myvector.push_back(78);
    myvector.push_back(16);

    // 現(xiàn)在前排等于78,后排等于16

    myvector.front() -= myvector.back();

    std::cout << "myvector.front() is now " << myvector.front() << '\n';

    return 0;
}

6.4 std::vector::back
返回最后一個元素的引用狂票。

      reference back();
const_reference back() const;

返回對向量中最后一個元素的引用候齿。
與成員向量::: end返回僅在此元素之后的迭代器不同,該函數(shù)返回直接引用苫亦。
在空容器上調(diào)用此函數(shù)會導(dǎo)致未定義的行為毛肋。

// vector::back
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;

  myvector.push_back(10);

  while (myvector.back() != 0)
  {
    myvector.push_back ( myvector.back() -1 );
  }

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

  return 0;
}

6.5 std::vector::data (C++11)
返回指向容器中第一個元素的指針。

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

返回指向向量內(nèi)部用于存儲其擁有的元素的內(nèi)存數(shù)組的直接指針屋剑。
由于保證向量中的元素以與向量表示相同的順序存儲在連續(xù)的存儲位置中,因此檢索到的指針可以偏移以訪問數(shù)組中的任何元素诗眨。

// vector::data
#include <iostream>
#include <vector>

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

  int* p = myvector.data();

  *p = 10;
  ++p;
  *p = 20;
  p[2] = 100;

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

  return 0;
}
  1. Modifiers 內(nèi)容修改

7.1 std::vector::assign
用新元素替換原有內(nèi)容唉匾。

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);

將新內(nèi)容分配給向量,替換其當(dāng)前內(nèi)容匠楚,并相應(yīng)地修改其大小巍膘。

在范圍版本(1)中溜徙,新內(nèi)容是從第一個到最后一個范圍內(nèi)的每個元素以相同順序構(gòu)造的元素浓恳。
在填充版本(2)中负乡,新內(nèi)容是n個元素为鳄,每個元素都初始化為val的副本偿洁。
在初始化程序列表版本(3)中荚醒,新內(nèi)容是作為初始化程序列表傳遞的值的副本宜岛,順序相同姜贡。
如果發(fā)生重新分配,則使用內(nèi)部分配器(通過其特征)分配和取消分配存儲磷支。 它還可用于銷毀所有現(xiàn)有元素谒撼,并構(gòu)造新元素。

// vector assign
#include <iostream>
#include <vector>

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

    first.assign(7, 100);             // 7個整數(shù)雾狈,值為100

    std::vector<int>::iterator it;
    it = first.begin() + 1;

    second.assign(it, first.end() - 1); // 從第2個值到到數(shù)第1個值

    int myints[] = { 1776,7,4 };
    third.assign(myints, myints + 3);   // 從數(shù)組分配

    std::cout << "Size of first: " << int(first.size()) << '\n';
    std::cout << "Size of second: " << int(second.size()) << '\n';
    std::cout << "Size of third: " << int(third.size()) << '\n';
    return 0;
}

7.2 std::vector::push_back
在序列的尾部添加一個元素廓潜。

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

在向量的末尾,當(dāng)前向量的最后一個元素之后善榛,添加一個新元素辩蛋。 val的內(nèi)容被復(fù)制(或移動)到新元素。
這有效地將容器大小增加了一個移盆,這會導(dǎo)致分配的存儲空間自動重新分配悼院,前提是(且僅當(dāng))新向量大小超過當(dāng)前向量容量時。

// vector::push_back
#include <iostream>
#include <vector>

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

    std::cout << "請輸入一些整數(shù) (輸入0結(jié)束):\n";

    do {
        std::cin >> myint;
        myvector.push_back(myint);
    } while (myint);

    std::cout << "myvector stores " << int(myvector.size()) << " numbers.\n";

    return 0;
}

7.3 std::vector::pop_back
移出序列尾部的元素味滞。

void pop_back();

刪除向量中的最后一個元素樱蛤,從而有效地將容器大小減小了一個。
這會破壞已刪除的元素剑鞍。

// vector::pop_back
#include <iostream>
#include <vector>

int main()
{
    std::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();
    }

    std::cout << "myvector的元素總計為: " << sum << '\n';

    return 0;
}

7.4 std::vector::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);

通過在元素前面的指定位置插入新元素來擴展向量,有效地通過插入元素的數(shù)量增加容器的大小蚁署。
這將導(dǎo)致當(dāng)且僅當(dāng)新矢量大小超過當(dāng)前矢量容量時自動重新分配分配的存儲空間便脊。
因為向量使用數(shù)組作為其底層存儲,所以在向量結(jié)尾以外的位置插入元素會導(dǎo)致容器將位置之后的所有元素重新定位到新位置光戈。與其他類型的序列容器(如list或forward_list)對同一操作執(zhí)行的操作相比哪痰,這通常是一種低效的操作。
參數(shù)決定插入多少個元素以及它們被初始化到哪些值:

// inserting into a vector
#include <iostream>
#include <vector>

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

    it = myvector.begin();
    it = myvector.insert(it, 200);

    myvector.insert(it, 2, 300);

    // "it" 不再有效久妆,請換一個新的:
    it = myvector.begin();

    std::vector<int> anothervector(2, 400);
    myvector.insert(it + 2, anothervector.begin(), anothervector.end());

    int myarray[] = { 501,502,503 };
    myvector.insert(myvector.begin(), myarray, myarray + 3);

    std::cout << "myvector contains:";
    for (it = myvector.begin(); it < myvector.end(); it++)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

7.5 std::vector::erase
移出一個元素或一段元素晌杰。

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

從向量中移除單個元素(位置)或一系列元素([第一個,最后一個)筷弦。
這有效地減少了容器的大小肋演,減少了被銷毀的元素的數(shù)量。
因為向量使用一個數(shù)組作為其底層存儲烂琴,所以在向量末尾以外的位置刪除元素會導(dǎo)致容器在刪除段后將所有元素重新定位到新位置爹殊。與其他類型的序列容器(如list或forward_list)對同一操作執(zhí)行的操作相比,這通常是一種低效的操作奸绷。

// erasing from vector
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> myvector;

    // set some values (from 1 to 10)
    for (int i = 1; i <= 10; i++) myvector.push_back(i);

    // erase the 6th element
    myvector.erase(myvector.begin() + 5);

    // erase the first 3 elements:
    myvector.erase(myvector.begin(), myvector.begin() + 3);

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

    return 0;
}

7.6 std::vector::swap
交換兩個容器的所有元素梗夸。

void swap (vector& x);

通過x的內(nèi)容交換容器的內(nèi)容,x是另一個相同類型的向量對象号醉。尺寸可能不同反症。
調(diào)用此成員函數(shù)后辛块,此容器中的元素是調(diào)用之前在x中的元素,x的元素是此調(diào)用之前在x中的元素惰帽。所有迭代器憨降、引用和指針對于交換的對象仍然有效。
請注意该酗,存在一個同名的非成員函數(shù)swap授药,并使用類似于此成員函數(shù)的優(yōu)化重載該算法。

// swap vectors
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> foo(3, 100);   // 100 100 100
    std::vector<int> bar(5, 200);   // 200 200 200 200 200

    foo.swap(bar);

    std::cout << "foo contains:";
    for (unsigned i = 0; i < foo.size(); i++)
        std::cout << ' ' << foo[i];
    std::cout << '\n';

    std::cout << "bar contains:";
    for (unsigned i = 0; i < bar.size(); i++)
        std::cout << ' ' << bar[i];
    std::cout << '\n';

    return 0;
}

7.7 std::vector::clear

移出所有的元素呜魄,容器大小變?yōu)?0悔叽。

void clear() noexcept;

從向量中移除所有元素(已銷毀),使容器的大小為0爵嗅。
不能保證會發(fā)生重新分配娇澎,也不能保證由于調(diào)用此函數(shù)而改變向量容量。強制重新分配的典型替代方法是使用swap:

// clearing vectors
#include <iostream>
#include <vector>

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

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

  myvector.clear();
  myvector.push_back (1101);
  myvector.push_back (2202);

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

  return 0;
}

7.8 std::vector::emplace(C++11)
在指定的位置直接生成一個元素睹晒。
emplace() 每次只能插入一個元素趟庄,而不是多個。 emplace() 在插入元素時伪很,是在容器的指定位置直接構(gòu)造元素戚啥,而不是先單獨生成,再將其復(fù)制(或移動)到容器中锉试。因此猫十,在實際使用中,推薦大家優(yōu)先使用 emplace()呆盖。

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

通過在位置插入新元素來擴展容器拖云。 這個新元素是使用args作為其構(gòu)造參數(shù)構(gòu)建的。
這有效地將容器尺寸增加了一個应又。
當(dāng)且僅當(dāng)新向量大小超過當(dāng)前向量容量時宙项,才會自動重新分配已分配的存儲空間。
由于向量使用數(shù)組作為其基礎(chǔ)存儲株扛,因此在向量末端以外的位置插入元素會導(dǎo)致容器將位置后的所有元素都移動一個到其新位置杉允。 與其他類型的序列容器(例如list或forward_list)執(zhí)行的操作相比,這通常是一種低效的操作席里。 請參閱emplace_back以獲取直接在末尾擴展容器的成員函數(shù)。
通過轉(zhuǎn)發(fā)帶有args的allocator_traits :: construct來就地構(gòu)建元素拢驾。
存在一個類似的成員函數(shù)奖磁,插入,該成員函數(shù)將現(xiàn)有對象復(fù)制或移動到容器中繁疤。

// vector::emplace
#include <iostream>
#include <vector>

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

  auto it = myvector.emplace ( myvector.begin()+1, 100 );
  myvector.emplace ( it, 200 );
  myvector.emplace ( myvector.end(), 300 );

  std::cout << "myvector contains:";
  for (auto& x: myvector)
    std::cout << ' ' << x;
  std::cout << '\n';

  return 0;
}

7.9 std::vector::emplace_back (C++11)
在序列尾部生成一個元素咖为。
emplace_back() 的執(zhí)行效率比 push_back() 高秕狰。因此,在實際使用時躁染,建議大家優(yōu)先選用 emplace_back()鸣哀。

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

在最后構(gòu)造并插入元素在向量的最后一個元素之后,在向量的末尾插入一個新元素吞彤。 使用args作為其構(gòu)造函數(shù)的參數(shù)在適當(dāng)?shù)奈恢脴?gòu)造此新元素我衬。
這有效地將容器大小增加了一個,這會導(dǎo)致分配的存儲空間自動重新分配饰恕,前提是(且僅當(dāng))新向量大小超過當(dāng)前向量容量時挠羔。
通過轉(zhuǎn)發(fā)帶有args的allocator_traits :: construct來就地構(gòu)建元素。
存在類似的成員函數(shù)push_back埋嵌,該函數(shù)將現(xiàn)有對象復(fù)制或移動到容器中破加。

// vector::emplace_back
#include <iostream>
#include <vector>

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

  myvector.emplace_back (100);
  myvector.emplace_back (200);

  std::cout << "myvector contains:";
  for (auto& x: myvector)
    std::cout << ' ' << x;
  std::cout << '\n';

  return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市雹嗦,隨后出現(xiàn)的幾起案子范舀,更是在濱河造成了極大的恐慌,老刑警劉巖了罪,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锭环,死亡現(xiàn)場離奇詭異,居然都是意外死亡捶惜,警方通過查閱死者的電腦和手機田藐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吱七,“玉大人汽久,你說我怎么就攤上這事∮徊停” “怎么了景醇?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長吝岭。 經(jīng)常有香客問我三痰,道長,這世上最難降的妖魔是什么窜管? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任散劫,我火速辦了婚禮,結(jié)果婚禮上幕帆,老公的妹妹穿的比我還像新娘获搏。我一直安慰自己,他們只是感情好失乾,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布常熙。 她就那樣靜靜地躺著纬乍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪裸卫。 梳的紋絲不亂的頭發(fā)上仿贬,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音墓贿,去河邊找鬼茧泪。 笑死,一個胖子當(dāng)著我的面吹牛募壕,可吹牛的內(nèi)容都是我干的调炬。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼舱馅,長吁一口氣:“原來是場噩夢啊……” “哼缰泡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起代嗤,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤棘钞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后干毅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宜猜,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年硝逢,在試婚紗的時候發(fā)現(xiàn)自己被綠了姨拥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡渠鸽,死狀恐怖叫乌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情徽缚,我是刑警寧澤憨奸,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站凿试,受9級特大地震影響排宰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜那婉,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一板甘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧详炬,春花似錦虾啦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至呻率,卻和暖如春硬毕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背礼仗。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工吐咳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人元践。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓韭脊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親单旁。 傳聞我的和親對象是個殘疾皇子沪羔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容