7

我正在阅读的这本书在迭代一个vector

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

假设 v 被声明为vector<int> v,换句话说,我们知道这个集合中元素的类型是int

是否auto以任何方式更好或更喜欢使用?

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

为什么?

4

2 回答 2

6

是的。auto是首选。因为如果您更改vfrom 的声明:

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

对此:

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

如果你int &在 中使用for,那么你也必须改变它。但是有了auto,就不需要改变了!

在我看来,使用 withauto或多或少类似于对 interface 进行编程。因此,如果您+=在循环中进行操作,并且您并不真正关心循环变量的类型e,只要类型支持+=操作,那么auto解决方案是:

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

在此示例中,您只关心右侧的e支撑类型。它甚至适用于已定义的用户定义类型,或者 where是支持隐式转换的类型。就好像您正在编程接口:+=intoperator+=(int)operator+=(T)Tint

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 评论中的要点值得注意。

于 2012-08-23T02:48:42.430 回答
1

在您的第一个示例中,您对向量元素的依赖程度较低。

假设在一个月内,您需要向量存储更大的整数,因此您将不得不使用std::vector<int64_t>或其他更宽的类型。现在所有迭代该向量的代码都是无效的。您必须修改每个:

for (int &e: v) {}

为一个:

for (int64_t &e: v) {}

这就是为什么最好只auto推断内部类型。这样,您可以将存储在向量中的类型修改为另一个兼容的类型,并且您的所有代码仍然可以工作。

于 2012-08-23T02:48:39.883 回答