在向量上迭代时,自动类型与具体类型

Auto vs concrete type when iterating over vector?

本文关键字:类型 向量 迭代      更新时间:2023-10-16

我正在读的书在迭代vector 时提供了这个例子

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

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

使用auto在任何方面都更好或更可取吗?

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

为什么?

是。优选CCD_ 5。因为如果您将v的声明更改为:

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

到此:

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

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

在我看来,使用auto或多或少就像是对接口进行编程。因此,如果您在循环中执行操作+=,并且您并不真正关心循环变量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) {}

对于a:

for (int64_t &e: v) {}

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