C 11新特性 for遍歷

2022-09-17 04:33:10 字數 3180 閱讀 5214

熟悉c++98/03的對於for迴圈就再了解不過了,如果我們要遍歷乙個陣列,那麼在c++98/03中的實現方式:

int arr[10] = ;  

for (int i = 0; i < 10; i++)

cout

<< arr[i];

而遍歷容器類的for如下:

std::vector

vec ;

for (std::vector

::iterator itr = vec.begin(); itr != vec.end(); itr++)

cout

<< *itr;

不管上面哪一種方法,都必須明確的確定for迴圈開頭以及結尾條件,而熟悉c#或者python的人都知道在c#和python中存在一種for的使用方法不需要明確給出容器的開始和結束條件,就可以遍歷整個容器,幸運的是c++11中引入了這種方法也就是基於範圍的for迴圈,用基於範圍的for迴圈改寫上面兩個例子:

int arr[10] = ;  

for (auto n : arr)

cout

<< n;

std::vector

vec ;

for (auto n :vec)

std::cout

<< n;

可以看到改寫後的使用方法簡單了很多,**的可讀性提公升了乙個檔次,但是需要注意的在上述對容器的遍歷是唯讀的,也就是說遍歷的值是不可修改的,如果需要修改其中元素,可以宣告為auto &:

#include

#include

using

namespace

std;

intmain();

cout

<< "修改前"

<< endl;

for (auto &n : vec)

std::cout

<< n++;

cout

<< endl;

cout

<< "修改後"

使用時需要注意的地方

1.注意auto自動推導的型別

雖然基於範圍的for迴圈使用起來非常的方便,我們不用再去關注for的開始條件和結束條件等問題了,但是還是有一些細節問題在使用的時候需要注意,來看下對於容器map的遍歷:

std::map

map = , , };

for (auto &val : map)

cout

<< val.first << "->"

<< val.second << endl;

為什麼是使用val.first,val.second而不是直接輸出value呢?在遍歷容器的時候,auto自動推導的型別是容器的value_type型別,而不是迭代器,而map中的value_type是std::pair,也就是說val的型別是std::pair型別的,因此需要使用val.first,val.second來訪問資料。

2.注意容器本身的約束

使用基於範圍的for迴圈還要注意一些容器類本身的約束,比如set的容器內的元素本身有容器的特性就決定了其元素是唯讀的,哪怕的使用了引用型別來遍歷set元素,也是不能修改器元素的,看下面例子:

set ss = ;  

for (auto& n : ss)

cout

<< n++ << endl;

上述**定義了乙個set,使用引用型別遍歷set中的元素,然後對元素的值進行修改,該段**編譯失敗:error c3892: 'n' : you cannot assign to a variable that is const。同樣對於map中的first元素也是不能進行修改的。

3.當冒號後不是容器而是乙個函式

再來看看假如我們給基於範圍的for迴圈的:冒號後面的表示式不是乙個容器而是乙個函式,看看函式會被呼叫多少次?

可以看出,如果冒號後面的表示式是乙個函式呼叫時,函式僅會被呼叫一次。

4.不要在for迴圈中修改容器

#include

#include

using

namespace

std;

vector

vec = ;

intmain

()system("pause");

return0;}

上述**在遍歷vector時,在容器內插入乙個元素7,執行上述**程式崩潰了。

究其原因還是由於在遍歷容器的時候,在容器中插入乙個元素導致迭代器失效了,因此,基於範圍的for迴圈和普通的for迴圈一樣,在遍歷的過程中如果修改容器,會造成迭代器失效,(有關迭代器失效的問題請參閱c++ primer這本書,寫的很詳細)也就是說基於範圍的for迴圈的內部實現機制還是依賴於迭代器的相關實現。

C 11新特性學習

lambda表示式用於建立匿名的函式物件,語法為 函式可訪問的的外部變數 函式引數 返回值型別 如 int a 1,b 2 int c b int x int b 表示函式中可以訪問外部變數b,而且引數b是按值傳遞,b 表示引數b是按引用傳遞,表示可以訪問所有外部變數,並且是用按值傳遞方式,類似,也...

C 11 新特性試用

在c 11之前,auto關鍵字用來指定儲存期。在新標準中,它的功能變為型別推斷。auto現在成了乙個型別的佔位符,通知編譯器去根據初始化 推斷所宣告變數的真實型別。各種作用域內宣告變數都可以用到它。例如,名空間中,程式塊中,或是for迴圈的初始化語句中。auto i 42 i is an int a...

C 11 新特性總結

vs2012以上版本支援 一.auto的使用 auto func less 自動表示函式指標 auto ite vector a.begin 自動表示stl的迭代器 auto p new foo 自動表示變數指標等變數 二.decltype int x 3 decltype x y x 從變數或表示...