【讀書筆記】【深入應用C++11】1.4 基於範圍的for循環

摘自:深入應用C++:代碼優化與工程級應用

1.4.1 for循環的新用法

std::for_each()

使用std::for_each()做循環,不需要關心迭代器的概念,只需要關心容器的類型。如:

#include <algorithm>
void do_count(int n)
{
        cout<<n<<endl;
}
vector<int> vect={1,2,3,4,5,6,7,8,9,0};
std::for_each(vect.begin(),vect.end(),do_count);

第三個參數可以用函數指針,也可以用lambda表達式。

基於範圍的for循環

在C++11中,提供了基於範圍的for循環。如:

vector<int> vect={1,2,3,4,5,6,7,8,9,0};
for(auto num:vect)
{
        cout<<num<<endl;
}

對於冒號前面的局部變量聲明,只要能夠支持容器類型的隱式轉換即可。如:

vector<long long int> vect={1,2,3,4,5,6,7,8,9,0};
for(int num:vect)
{
        cout<<num<<endl;
}

如果要修改容器中的值,需要使用引用。如:

vector<int> vect={1,2,3,4,5,6,7,8,9,0};
for(int &num:vect)
{
        num++;
        cout<<num<<endl;
}

1.4.2 基於範圍的for循環的使用細節

  • 基於範圍的for循環,與普通for循環一樣,遵循容器本身的特性:

    • 對於map容器,var(元素)的類型是:std:pair,需要使用var.first和var.second來提取鍵值。
    • 對與map容器,var.first是隻讀的(const T&)。
    • 對於set容器,var(元素)是隻讀的。
    map<string,int> mm={{"Hello",1},{"World",2}};
    for(pair<string,int> var:mm)
    {
        cout<<var.first<<" "<<var.second<<endl;
    }
  • 基於範圍的for循環,冒號後面的表達式只會被計算一次。
  • 基於範圍的for循環,是普通for循環的語法糖。與普通for循環一樣,迭代時修改容器可能會導致迭代器失效。
    for(auto var:array)
    {
        cout<<var<<endl;
    }

等價於:

    for(auto begin=array.begin(),end=array.end();begin!=end;begin++)
    {
        cout<<*begin<<endl;
    }

1.4.3 讓基於範圍的for循環支持自定義類型

爲了使自定義的數據類型支持基於範圍的for循環,需要定義begin和end迭代器。
編譯器通過以下方式查找begin和end迭代器:

  • 普通數組,begin爲數組的首地址,end爲首地址加數組長度。
  • 類對象,查找內部的begin和end成員函數。
  • 否則,試圖使用全局的begin和end函數。

基於範圍for循環的自定義類型實現

待續

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章