我正在阅读的书在迭代vector
for (auto &e: v) {
cout << e << endl;
}
假设v声明为vector<int> v
,换句话说,我们知道此集合中的元素类型为int
。
以任何方式使用auto
更好还是更喜欢?
for (int &e: v) {
cout << e << endl;
}
为什么?
答案 0 :(得分:6)
是。 auto
是首选。因为如果您更改v
的声明:
std::vector<int> v; //before
到此:
std::vector<float> v; //after
如果您在int &
中使用for
,那么您也必须更改它。但是使用auto
,无需更改!
在我看来,使用auto
或多或少像programming to interface。因此,如果您在循环中执行操作+=
,并且您并不真正关心循环变量e
的类型,只要该类型支持+=
操作,那么{{ 1}}是解决方案:
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
}
但与此同时,@ David的评论值得注意。
答案 1 :(得分:1)
在第一个示例中,您对向量元素的依赖性较小。
假设在一个月内,您需要向量存储较大的整数,因此您必须使用std::vector<int64_t>
或其他更宽的类型。现在遍历该向量的代码的所有都是无效的。你必须修改每个:
for (int &e: v) {}
对于:
for (int64_t &e: v) {}
这就是为什么让auto
推断出内部类型更好的原因。这样你就可以修改你的矢量中存储的另一个兼容的类型,你的所有代码仍然有用。