2010-05-13 36 views
9

我想为STL list迭代器获得较远的下一个值,但它没有实现operator+,vector虽然有。为什么以及如何获得我想要的价值?为什么只有随机访问迭代器在C++中实现operator +?

我想我可以做到这一点,如果我打电话operator++几次,但没有那么一点点脏?

我想要做的是以下几点:

list<int> l; 
...omitted... 
list<int>::iterator itr = l.begin() + 3; // but, list iterator does not have 
             // operator+ 

什么是我想要的最好的解决办法?

+2

(几乎)无关:您需要确保有可能达到此位置,否则您将调用未定义的行为。虽然从'list :: begin()'很容易,但在更通用的情况下,知道(对于非RandomAccessIterator)与列表 :: end()相距的唯一方法是调用std ::距离...... O(N)。 – 2010-05-13 18:31:14

+0

这个主题有两个很好的答案。 +1给社区! – 2010-05-13 18:46:32

回答

17

如果您无权访问C++ 11,则还可以使用std::next(和prev)或Boost提供的等效项。

list<int>::iterator itr = std::next(l.begin(), 3); 

理由:std::advance是很难使用(它的工作原理是副作用,而不是返回一个副本)。

+2

很高兴知道。我一直想知道为什么'std :: advance'是通过副作用而不是功能性的。 – 2010-05-13 18:32:48

+1

@RSam:我一直认为这是因为'std :: advance'是为了模仿++ itr或operator + =,如果适当的话。迭代器算法通常用这些术语编写,所以包装它们是最有意义的。 – 2010-05-13 20:05:26

+0

如果你想要一个副本,你必须自己创建一个副本。这在C++中很常见。 – mschneider 2011-02-15 04:01:50

37

你想用std::advance

list<int>::iterator itr = l.begin(); 
std::advance(itr, 3); 

advance将使用operator+和完整在常数时间如果迭代器是随机访问,同时将循环在operator++和完整的线性时间,如果迭代器不是随机访问。  

原因是为了让您控制复杂性要求。如果你关心操作的复杂性,你可以使用operator+并且获得恒定的时间,但是这只能用随机访问迭代器进行编译。如果你不关心你使用的复杂度std::advance,它将始终工作,但复杂度会根据迭代器而变化。

+3

+1简单,清晰,彻底。 – wilhelmtell 2010-05-13 18:15:33

相关问题