摘自:深入應用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函數。