【发布时间】:2010-12-12 16:34:17
【问题描述】:
我发现自己写了很多:
int location =2;
vector<int> vec;
vector<int>::iterator it=vec.begin();
/..../
std::advance(it, location);
而不是
it= it + 5;
首选/推荐方式是什么?
【问题讨论】:
我发现自己写了很多:
int location =2;
vector<int> vec;
vector<int>::iterator it=vec.begin();
/..../
std::advance(it, location);
而不是
it= it + 5;
首选/推荐方式是什么?
【问题讨论】:
添加仅适用于随机访问迭代器。 std::advance 将适用于各种迭代器。只要您只处理向量中的迭代器,它就没有真正的区别,但std::advance 使您的代码更通用(例如,您可以用list 替换vector,这部分仍然可以工作) .
对于那些关心的人,标准将advance 和distance 描述如下(§24.3.4/1):
由于只有随机访问迭代器提供 + 和 - 运算符,因此库提供了两个函数模板
advance和distance。这些函数模板将+和-用于随机访问迭代器(因此它们的时间是常数);对于输入、前向和双向迭代器,他们使用++来提供线性时间实现。
另请注意,从 C++11 开始,标准向 std::next 添加了一个参数,因此您可以使用它前进指定的数量(和 std::prev 类似)。与std::advance 的区别在于它返回修改后的迭代器(std::advance 没有),这在某些情况下可能很方便。
【讨论】:
这取决于你需要什么:
如果您需要通用性,请使用std::advance(it,2)。如果有人出现并将您的std::vector 更改为std::list,代码仍然可以编译,即使现在推进需要线性时间而不是恒定时间。
如果您需要性能,请使用it+=2。如果有人出现并将您的std::vector 更改为std::list,则代码将无法编译,并指出(可能带有有用的注释)一个严重的性能问题。
【讨论】:
这取决于迭代器。 it=it+5 如果受支持会更快(仅在随机访问迭代器上受支持)。如果你想推进一个能力较差的迭代器(例如一个前向迭代器或一个双向迭代器),那么你可以使用std::advance,但它会更慢,因为它实际上会遍历所有中间元素。
【讨论】:
advance 可能会在+ 产生内联代码的情况下使用函数调用(例如,如果 vector::iterator 是一个简单的指针)。
std::advance 也适用于非随机迭代器,而+= 版本适用于随机访问序列(向量等)。
【讨论】:
std::adnvance 是通用的 - 如果您不总是知道底层容器的类型,它很有用 - 它适用于所有情况。
然而它是高效的:std::advance 将在它传递一个 RandomAccessIterator 时进行优化(如来自 std::vector 的一个),并会增加 ForwardAccessIterator 循环中的迭代器(如 std::list 中的一个)。
【讨论】:
使用 std::advance。它同样高效(它使用迭代器特征来为随机访问迭代器进行迭代器添加),并且更通用,因为它也适用于其他类型的迭代器。
【讨论】:
如果您永远不会更改容器(而且您可能不会),请使用 +,因为它易于查看和理解,并且使代码不那么混乱。
如果您想更改容器,或者如果您正在使用可能在各种容器类型上实例化的模板,请使用 Advance,因为它适用于任何东西。
作为一般规则,我不担心更改容器类型,因为我发现当我必须更改容器类型时,我最终还是会重新访问使用该容器的所有地方,以确保我'我不做任何突然愚蠢的事情(比如从列表中间随机抽取元素)。
【讨论】: