推进std :: vector std :: advance VS运算符+的迭代器?

时间:2009-11-03 15:34:53

标签: c++ stl

我发现自己写了很多内容:

int location =2;
vector<int> vec;
vector<int>::iterator it=vec.begin();

/..../
std::advance(it, location);

而不是

 it= it + 5;

首选/推荐方式是什么?

7 个答案:

答案 0 :(得分:15)

添加仅适用于随机访问迭代器。 std :: advance将适用于各种迭代器。只要你只将迭代器处理成向量,它就没有什么区别,但是std :: advance使你的代码更加通用(例如,你可以用一个列表代替向量,那部分仍然可以工作)。

编辑:对于那些关心的人,标准描述advancedistance如下(§24.3.4/ 1):

  

由于只有随机访问迭代器提供了+和 - 运算符,因此该库提供了两个函数模板advancedistance。这些函数模板使用+-作为随机访问迭代器(因此,它们是常量时间);对于输入,转发和双向迭代器,它们使用++来提供线性时间实现。

答案 1 :(得分:6)

这取决于您的需求:

如果您需要 通用性 ,请使用std::advance(it,2)。如果有人出现并将std::vector更改为std::list,则代码仍会编译,即使现在提前需要线性时间而不是常量时间。

如果您需要 效果 ,请使用it+=2。如果有人出现并将std::vector更改为std::list,则代码将无法编译,指向(可能带有帮助的评论)严重的性能问题。

答案 2 :(得分:0)

这取决于迭代器。 it=it+5如果支持它会更快(它只在随机访问迭代器上支持)。如果你想推进功能较弱的迭代器(例如前向迭代器或双向迭代器),那么你可以使用std::advance,但它更慢,因为它实际上遍历所有中间元素。

答案 3 :(得分:0)

std::advance也适用于非随机迭代器,而+=版本适用于随机访问序列(矢量等)。

答案 4 :(得分:0)

std::adnvance是通用的 - 如果您不总是知道底层容器的类型,它会很有用 - 它适用于所有情况。

但效率很高:如果std::advance传递了一个RandomAccessIterator(如std::vector中的一个),它会进行优化,并会为ForwardAccessIterator增加迭代器的循环次数(就像std::list中的那个一样)。

答案 5 :(得分:0)

使用std :: advance。它同样有效(它使用迭代器特性来为随机访问迭代器添加迭代器),并且更通用,因为它也适用于其他类型的迭代器。

答案 6 :(得分:0)

如果您永远不会更改容器(并且您可能不是),请使用+,因为它易于查看和理解,并使代码更简洁。

如果您认为要更改容器,或者如果您在可能在各种容器类型上实例化的模板内部工作,请使用advance,因为它适用于任何容器。

作为一般规则,我不担心更改容器类型,因为我发现当我必须更改容器类型时,我最终会重新访问容器被使用的任何地方,只是为了确保我'我没有做任何突然愚蠢的事情(比如从列表中间随机抽取元素)。