2012-08-23 73 views
7

這本書我讀報價這個例子遍歷一個vector迭代向量時自動vs混凝土類型?

for (auto &e: v) { 
    cout << e << endl; 
} 

假設v當被聲明爲vector<int> v,換句話說,我們知道元素的這個集合裏面的類型是int

以任何方式使用auto更好還是更喜歡?

for (int &e: v) { 
    cout << e << endl; 
} 

爲什麼?

回答

6

是的。 auto是優選的。因爲如果你改變v從聲明:

std::vector<int> v; //before 

這樣:

std::vector<float> v; //after 

如果您在使用forint &,那麼你就必須改變這一點。但與auto,沒有必要改變!

在我看來,與auto合作是或多或少像programming to interface。所以,如果你在循環做手術+=,你真的不只要類型支持+=操作關心的循環變量e的類型,然後auto是解決方案:

for(auto & e : v) 
{ 
     e += 2; 
} 

在這例如,您所關心的是e的類型支持+=,而右邊是int。它甚至可以用於用戶定義類型,它定義了operator+=(int)operator+=(T),其中T是一種支持從int進行隱式轉換的類型。這是因爲如果你正在編寫接口:

std::vector<Animal*> animals; 
animals.push_back(new Dog()); 
animals.push_back(new Cat()); 
animals.push_back(new Horse()); 

for(size_t i = 0 ; i < animals.size(); ++i) 
{ 
     animals[i]->eat(food); //program to interface 
} 

當然,你願意寫這個循環爲:

for(Animal * animal : animals) 
{ 
     animal->eat(food); //still program to interface 
} 

或者簡單:

for(auto animal : animals) 
{ 
     animal->eat(food); //still program to interface 
} 

這是仍然programming to interface

但是與此同時,@ David的評論中的觀點值得注意。

+6

這可以通過兩種方式讀取,最好是得到一個編譯錯誤,指出int'不能從float中設置',而不是編譯器默默地接受代碼來處理ints ...不是說'擁有'int&'是一個更好的主意,這一切都取決於你在'for'循環體中做了什麼,如果它不依賴於確切的類型'auto'將會更好 –

+0

@DavidRodríguez-dribeas :我認爲你所說的是非常不尋常的情況。通常,我們必須將'int'更改爲'float',在這種情況下'auto'是更好的解決方案。 – Nawaz

+1

同意。在大多數情況下,'auto&'會做...但我不舒服的類型不明確無處不在:)(除非我真的不想知道!) –

1

在您的第一個示例中,您對矢量的元素的依賴性較少。

假設在一個月內,你需要你的向量存儲較大的整數,所以你將不得不使用一個std::vector<int64_t>或其他一些更寬的類型。現在所有的迭代遍歷該向量的代碼都是無效的。你必須修改每個:

for (int &e: v) {} 

對於一個:

for (int64_t &e: v) {} 

那就是爲什麼最好只讓auto推斷出內部類型。通過這種方式,您可以修改存儲在您的矢量中的另一個兼容類型,並且您的所有代碼仍然可以工作。