這次要講的是:c++11統一初始化、統一begin()/end()和for-loop循環如何簡化我們的程序
- 初始化列表
c++11之前有各種各樣的初始化語法,有時候初始化的時候還挺麻煩,比較典型的如vector和map的初始化。
vector<int> v; for(int i=0;i<10;i++) { v.push_back(i); } map<int,int> map; for(int i=0;i<10;i++) { map.insert(make_pair(i,i)); }
這種寫法比較繁瑣,而且不夠直觀。現在c++11中你可以這樣寫了:
vector<int> v = {0,1,2,3,4,5,6,7,8,9}; map<int,int> map = {{0,0},{1,1},{2,2,{3,3}};
不用再手動去push_back或者insert了,這樣寫很簡單也很直觀。不僅僅是容器的初始化可以這樣,普通的數組也可以這樣寫:
int int_array[3] = {1,2,3}; string str_array[3] = {"","",""};
其實對結構體和類也一樣可以很方便的初始化,例如:
struct A { int x; int y; };
vector<A> v在c++11之前如果要放入兩個結構體A的話,要這樣寫:
A a1; a1.x = 1; a1.y = 2; v.push_back(a1); A a2; a2.x = 1; a2.y = 2; v.push_back(a2);
vector<A>的初始化顯得十分繁瑣,現在c++11讓我們從這種繁瑣之中解脫出來了,c++11中可以這樣寫:
vector<A> v = {{1,2},{3,4}};
上面的代碼表示v中有兩個結構體A,內部成員變量x,y的初始化值為1,2以及3,4;一行代碼,一步到位,簡潔明了,是不是很清爽,我非常喜歡這種簡潔而直接的初始化方式。
- 統一的begin()/end()
c++11之前只有容器有自己的begin()和end(),我們可以很方便的按照統一的方式去遍歷集合,然而一些其他類型的數組沒有卻沒有begin()/end()導致我們不能按照統一的方式去遍歷集合。
vevtor<int> v; for(auto it=v.begin(); it!=v.end(); ++it) { //do something } int array[10];
對於array我們卻不能像vector那樣去遍歷。
現在c++11增加了非成員的begin()和end(), 就是說這個begin()和end()不是屬於某個類型的,而是所有集合和數組所共有的,使得我們可以按照統一的方式去遍歷集合和數組了。你可以一種通用方式去遍歷,類似於:
for(auto it = begin(range); it!=end(range); it++) { //do something }
這個range可以vecotr,map等容器,也可以是int類型的普通數組,這樣我們就可以統一的方式去遍歷容器和數組了,可以寫出更加泛化和通用的代碼了。
- for-loop循環
c++11新增了for-loop循環方式,上面遍歷容器的方法還可以寫成:
for(auto item : range) { } for(auto& item : range) { }
這種方式直接獲取range中的元素,可以以值或者引用方式獲取。這種方式比起之前的寫法要更簡潔了。這種for-loop寫法不僅僅對容器和數組有效,對自定義類型同樣有效,不過前提是自定義類型要實現begin(),end(),因為for-loop內部實現就是通過begin(),end()去迭代整個范圍的。
初始化列表和for-loop循環在c#和java中比較早就引入了,現在c++也趕上來了,c++11引入這些現代編程語言的特性,讓我們的代碼變得更簡潔、更modern。