1. 程式人生 > >C++11範圍for循環

C++11範圍for循環

stream [] AC end con getch char ron cast

範圍for循環:
1.基於範圍的for循環
for(元素類型 元素對象:容器對象)
{
循環體
}
(1.1)如果循環體由單條語句或者單個結構塊組成,可以省略花括號
(1.2)用元素對象依次結合容器對象中的每一個元素,每結合一個元素,執行依次循環體,直至容器內的所有元素都被結合完為止.
(1.3)不依賴於下標元素,通用
(1.4)不需要訪問叠代器,透明
(1.5)不需要定義處理函數,簡潔

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
using namespace
std; void print(int i) { cout << i << " "; } int _tmain(int argc, _TCHAR* argv[]) { int ai[] {65, 66, 67, 68, 69}; size_t size = sizeof(ai) / sizeof(ai[0]); vector<int> vi(ai, ai + size); //基於下標運算的for循環,不是所有的容器都支持下標運算,不通用 for (size_t i = 0; i < size; ++i) cout << ai[i]<<"
"; cout << endl; for (size_t i = 0; i < vi.size(); ++i) cout << vi[i]<<" "; cout << endl; //基於叠代器的for循環,需要指明容器兩端,且對叠代器做自增,必須了解叠代器的運算規則,不夠透明 for (int *it = ai; it != ai + size; ++it) cout << *it << " "; cout << endl; for (auto it = vi.begin(); it != vi.end(); ++it) cout
<< *it << " "; cout << endl; //基於泛型函數的for循環,需要提供針對元素的處理函數,對於一般性遍歷而言比較繁瑣 for_each(ai, ai + size, print); cout << endl; for_each(vi.begin(),vi.end(), print); cout << endl; for (auto a : ai) cout << a << " "; cout << endl; for (auto a : vi) cout << a << " "; cout << endl; for (auto &a : ai) ++a; for (auto &a : vi) --a; for (auto const &a : ai) cout << a << " "; cout << endl; for (auto const &a : vi) cout << a << " "; cout << endl; for (char a : ai) cout << a << " "; cout << endl; for (char a : vi) cout << a << " "; cout << endl; getchar(); return 0; }

2.範圍循環的註意事項
(2.1)對map和multimap容器使用範圍循環,每次拿到的元素既不是鍵也不是值,而是由鍵和值組成的pair
(2.2)在使用基於範圍的for循環時,不能違背容器本身的約束
(2.3)基於範圍的for循環,無論循環體執行多少次,冒號後面的表達式永遠只執行一次
(2.4)基於範圍的for循環,其底層實現依然要借助於容器的叠代器,
因此任何可能導致叠代器失效的結構性改變,都可能引發未定義的後果

 1 #include "stdafx.h"
 2 #include <iostream>
 3 #include <string>
 4 #include <map>
 5 #include <list>
 6 using namespace std;
 7 
 8 list<int> getScores(void)
 9 {
10 cout << __FUNCTION__ << endl;
11 return{ 70, 75, 80, 85, 90, 95 };
12 }
13 
14 int _tmain(int argc, _TCHAR* argv[])
15 {
16 //對map和multimap容器使用範圍循環,每次拿到的元素既不是鍵也不是值,而是由鍵和值組成的pair
17 multimap<string, int> msi;
18 msi.insert(make_pair("張飛", 100));
19 msi.insert(make_pair("趙雲", 90));
20 msi.insert(make_pair("關羽", 80));
21 for (auto c : msi)
22 cout << c.first << ":" << c.second << endl;
23 cout << endl;
24 for (auto it = msi.begin(); it != msi.end(); ++it)
25 cout << it->first << ":" << it->second << endl;
26 cout << endl;
27 
28 //在使用基於範圍的for循環時,不能違背容器本身的約束
29 /*for (pair<string,int> &c:msi)
30 if (c.first == "張飛")
31 c.first = "張菲菲";*/
32 for (auto c : msi)
33 cout << c.first << ":" << c.second << endl;
34 cout << endl;
35 //基於範圍的for循環,無論循環體執行多少次,冒號後面的表達式永遠只執行一次
36 for (auto score : getScores())
37 cout << score << " ";
38 cout << endl;
39 auto scores = getScores();
40 for (auto score : scores)
41 {
42 cout << score << " ";
43 //基於範圍的for循環,其底層實現依然要借助於容器的叠代器,
44 //因此任何可能導致叠代器失效的結構性改變,都可能引發未定義的後果
45 //scores.pop_front();
46 }
47 cout << endl;
48 getchar();
49 return 0;
50 }

3.使自己定義的容器類型支持範圍循環
一個類只要提供了分別獲取起始和終止叠代器的begin和end函數,就可以支持基於範圍的for循環

 1 #include "stdafx.h"
 2 #include <iostream>
 3 using namespace std;
 4 
 5 template <typename T, size_t S>
 6 class Array
 7 {
 8 public:
 9 T &operator[](size_t i)
10 {
11 return m_array[i];
12 }
13 T const &operator[](size_t i)const
14 {
15 return const_cast<Array&>(*this)[i];
16 }
17 //獲取起始叠代器
18 T *begin()
19 {
20 return m_array;
21 }
22 T const *begin()const
23 {
24 return const_cast<Array *>(this)->begin();
25 }
26 //獲取終止叠代器
27 T *end()
28 {
29 return m_array+S;
30 }
31 T const *end()const
32 {
33 return const_cast<Array *>(this)->end();
34 }
35 private:
36 T m_array[S];
37 };
38 
39 
40 int _tmain(int argc, _TCHAR* argv[])
41 {
42 int i = 0;
43 Array<int, 5> ai;
44 for (auto &a : ai)
45 a = ++i * 10;
46 auto const &cai = ai;
47 for (auto &a : cai)
48 cout << /*++*/a << " ";
49 cout << endl;
50 getchar();
51 return 0;
52 }

C++11範圍for循環