1. 程式人生 > 實用技巧 >c++11學習筆記(8)

c++11學習筆記(8)

(1)新標準引入了3個新成員,emplace_front, emplace和emplace_back,這些操作構造而不是拷貝元素,這些操作分別對應push_front,push,push_back,允許我們將元素放置在容器頭部,一個指定位置之前,容器尾部。
(2)當呼叫push或insert成員函式時,我們將元素型別的物件傳遞給它們,這些物件被拷貝到容器中。而當我們呼叫一個emplace成員函式時,則是將引數傳遞給元素型別的建構函式。emplace成員使用這些引數在容器管理的記憶體空間中直接構造元素。
(3)假定c儲存sales_data

c.emplace_back("45224", 25, 15.99
); c.push_back("45224", 25, 15.99); 上面這個是錯誤的 c.push_back(sales_data("45224", 25, 15.99));

其中正確的兩個呼叫都會建立新的sales_data物件,在呼叫emplace_back的時候,會在容器管理的記憶體空間中直接建立物件。而呼叫push_back則會建立一個區域性臨時物件,並將其壓入容器中。
(4)包括array在內的每個順序容器都有一個front成員,而除了forward_list之外的所有順序容器都有一個back成員函式。這兩個操作分別返回首元素和尾元素的引用。

if(!c.empty())
{
  auto val 
= *c.begin(), val2 = c.front;   auto last = c. end();   auto val3 = *(--last);   auto val4 = c back(); }

此程式用兩種不同的方式來獲取c中的首元素和尾元素的引用,直接的方法是呼叫front和back,而間接的方法是通過解引用begin返回的迭代器來過的首元素的引用,以及通過遞減然後解引用end返回的迭代器來獲得尾元素的引用。
(5)在容器中訪問元素的成員函式(front/back/at)返回的都是引用,如果容器是一個const物件,則返回值是const的信用。如果容器不是const的,則返回值是普通引用,我們可以用來改變元素的值。

if(!c.empty())
{
  c.front() = 42; 
  auto &v = c. back();
  v = 1024;//引用可以改變
  auto v2 = c. back();
  v2 = 0//沒有改變c中的元素
}

(6)下標運算子接受一個下標引數,返回容器中該位置的元素的引用,給定下標必須在範圍內。如果我們希望確保下標是合法的,可以使用at函式,at函式類似下標運算子,但如果下標越界,at會丟擲一個out_of_range異常。

vector<string> svec;
cout << svec[0];
cout << svec. at(0);

(7)非array容器有多種刪除元素的方式。
pop_front和pop_back成員函式分別刪除首元素和尾元素。和vector和string不支援push_front一樣,這些型別也不支援pop_front。類似的,forward_list不支援pop_back。和元素訪問成員函式類似,不能對一個空容器執行彈出操作。
(8)這些彈出操作返回void,如果你需要彈出的元素值,就必須在執行彈出之前儲存他。
(9)成員函式erase從容器中指定位置刪除元素,我們可以刪除一個由迭代器指定的單個元素,也可以刪除由一對迭代器指定的範圍內的所有元素。兩種形式的erase都返回指向刪除的最後一個元素之後位置的迭代器。
例如,下面的迴圈刪除一個list中的所有奇數元素。

list<int> lst = {0, 1, 2, 3, 4, 5, 6, 7};
auto it = lst. begin();
while(it != lst.end())
  if(*it % 2)//如果元素是奇數
    it = lst. erase(it);
  else
    ++it;

(10)可以接受一對迭代器刪除多個元素

slist. clear();
slist. erase(slist.begin(), slist.end());

(11)當新增或刪除一個元素時,刪除或新增元素之前的那個元素的後繼會發生改變。為了新增或刪除一個元素我們需要訪問其前驅,以便改變前驅的連結。但是,forward_list是單向連結串列,沒有簡單的方法過去一個元素的前驅。出於這個原因,在一個forward_list中新增或刪除元素的操作是通過改變給定元素之後的元素來完成的。這樣我們總是可以訪問到被新增或刪除操作所影響的元素。
(12)由於這些操作和其他容器上的操作實現方式不同,forward_list並未定義insert/emplace/erase。而且定義了名為insert_after/emplace_after/erase_after的操作。為了刪除elem3,應該用指向elem2的迭代器呼叫erase_after。為了支援這些操作,forward_list也定義了before_begin,它返回一個首前迭代器。這個迭代器允許我們在連結串列首元素之前並不存在的元素之後新增或刪除元素,也就是在連結串列首元素之前新增刪除元素。
(13)

forward_list<int> flst = {0, 1, 2, 3, 4, 5, 6};
auto prev = flst. before_begin();
auto curr = flst. begin();
while(curr != flst.end())
{
  if(*curr % 2)如果元素是奇數
    curr = flst. erase_after(prev);
  else
    prev = curr;
    ++curr;移動迭代器curr,指向下一個元素,prev指向curr之前的元素
}

(13)可以使用resize來增大或縮小容器,如果當前大小大於所要求的大小,容器後部的元素會被刪除,如果當前大小小於所要求的,會將新元素新增到容器後部。

list<int> ilist(10, 42);10和int,每個值都是42
ilist. resize(15);將5個0放在ilist的末尾
ilist. resize(25, -1);將10個-1新增到末尾
ilist. resize(5);從ilist末尾刪除20個元素