這本書我讀報價這個例子遍歷一個vector
迭代向量時自動vs混凝土類型?
for (auto &e: v) {
cout << e << endl;
}
假設v當被聲明爲vector<int> v
,換句話說,我們知道元素的這個集合裏面的類型是int
。
以任何方式使用auto
更好還是更喜歡?
for (int &e: v) {
cout << e << endl;
}
爲什麼?
這本書我讀報價這個例子遍歷一個vector
迭代向量時自動vs混凝土類型?
for (auto &e: v) {
cout << e << endl;
}
假設v當被聲明爲vector<int> v
,換句話說,我們知道元素的這個集合裏面的類型是int
。
以任何方式使用auto
更好還是更喜歡?
for (int &e: v) {
cout << e << endl;
}
爲什麼?
是的。 auto
是優選的。因爲如果你改變v
從聲明:
std::vector<int> v; //before
這樣:
std::vector<float> v; //after
如果您在使用for
int &
,那麼你就必須改變這一點。但與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
}
但是與此同時,@ David的評論中的觀點值得注意。
在您的第一個示例中,您對矢量的元素的依賴性較少。
假設在一個月內,你需要你的向量存儲較大的整數,所以你將不得不使用一個std::vector<int64_t>
或其他一些更寬的類型。現在所有的迭代遍歷該向量的代碼都是無效的。你必須修改每個:
for (int &e: v) {}
對於一個:
for (int64_t &e: v) {}
那就是爲什麼最好只讓auto
推斷出內部類型。通過這種方式,您可以修改存儲在您的矢量中的另一個兼容類型,並且您的所有代碼仍然可以工作。
這可以通過兩種方式讀取,最好是得到一個編譯錯誤,指出int'不能從float中設置',而不是編譯器默默地接受代碼來處理ints ...不是說'擁有'int&'是一個更好的主意,這一切都取決於你在'for'循環體中做了什麼,如果它不依賴於確切的類型'auto'將會更好 –
@DavidRodríguez-dribeas :我認爲你所說的是非常不尋常的情況。通常,我們必須將'int'更改爲'float',在這種情況下'auto'是更好的解決方案。 – Nawaz
同意。在大多數情況下,'auto&'會做...但我不舒服的類型不明確無處不在:)(除非我真的不想知道!) –