std::vector std::advance VS 运算符 +? 的高级迭代器
我发现自己写了很多以下内容:
int location =2;
vector<int> vec;
vector<int>::iterator it=vec.begin();
/..../
std::advance(it, location);
而不是
it= it + 5;
首选/推荐的方式是什么?
I found myself writing the following a lot:
int location =2;
vector<int> vec;
vector<int>::iterator it=vec.begin();
/..../
std::advance(it, location);
instead of
it= it + 5;
what is the Preferred/Recommended way ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
添加仅适用于随机访问迭代器。
std::advance
将适用于各种迭代器。只要您只处理向量中的迭代器,它就没有真正的区别,但是std::advance
使您的代码更加通用(例如,您可以替换list
对于向量
,该部分仍然有效)。对于那些关心的人,该标准对
提前
和距离
的描述如下(§24.3.4/1):另请注意,从 C++11 开始,标准向
std::next
添加了一个参数,因此您可以使用它前进指定的量(以及std::prev
> 类似地)。与 std::advance 的区别在于它返回修改后的迭代器(std::advance 不返回),这在某些情况下很方便。
Adding will only work with random access iterators.
std::advance
will work with all sorts of iterators. As long as you're only dealing with iterators into vectors, it makes no real difference, butstd::advance
keeps your code more generic (e.g. you could substitute alist
for thevector
, and that part would still work).For those who care, the standard describes
advance
anddistance
as follows (§24.3.4/1):Also note that starting with C++11, the standard added a parameter to
std::next
, so you can advance by a specified amount using it (andstd::prev
similarly). The difference fromstd::advance
is that it returns the modified iterator (whichstd::advance
doesn't), which can be convenient in some cases.这取决于您的需求:
如果您需要通用性,请使用
std::advance(it,2)
。如果有人将您的std::vector
更改为std::list
,代码仍然会编译,即使现在前进需要线性时间而不是恒定时间。如果您需要性能,请使用
it+=2
。如果有人将您的std::vector
更改为std::list
,则代码将无法编译,并指出(可能带有有用的注释)严重的问题。性能问题。That depends on what you need:
If you need genericity, use
std::advance(it,2)
. If someone comes along and changes yourstd::vector
into astd::list
, the code will still compile, even though advancing now takes linear time instead of constant time.If you need performance, use
it+=2
. If someone comes along and changes yourstd::vector
into astd::list
, the code will fail to compile, pointing (maybe with a helpful comment) at a serious performance issue.这取决于迭代器。如果支持的话,
it=it+5
会更快(仅在随机访问迭代器上受支持)。如果你想推进一个能力较差的迭代器(例如,前向迭代器或双向迭代器),那么你可以使用 std::advance ,但它的速度较慢,因为它实际上会遍历所有中间过程元素。It depends on the iterator.
it=it+5
is faster if it's supported (it's only supported on random access iterators). If you want to advance a less-capable iterator (e.g. a forward iterator, or a bidirectional iterator), then you can usestd::advance
, but it's slower because it actually walks across all of the intermediate elements.std::advance
也适用于非随机迭代器,而+=
版本则适用于随机访问序列(向量等)。std::advance
works on non-random iterators too while the+=
version on works on random access sequences (vectors and the like).std::adnvance
是通用的 - 如果您并不总是知道底层容器的类型,它会很有用 - 它适用于所有情况。但它是高效的:如果 std::advance 传递了 RandomAccessIterator(如来自 std::vector 的随机访问迭代器),则 std::advance 将会进行优化,并且会在 ForwardAccessIterator 的循环中增加迭代器(就像
std::list
中的一样)。std::adnvance
is generic - it is useful if you don't always know type of underlying container - it works in all cases.Yet it is efficient:
std::advance
will do an optimisation if it passed an RandomAccessIterator (like one fromstd::vector
) and will increase iterator in loop for ForwardAccessIterator (as like one instd::list
).使用 std::advance。它同样高效(它使用迭代器特征来对随机访问迭代器进行迭代器加法),并且更通用,因为它也适用于其他类型的迭代器。
Use std::advance. It is just as efficient (it uses iterator traits to just do iterator addition for random access iterators), and is more general in that it works on other kinds of iterators as well.
如果您永远不会更改容器(而且您可能不会),请使用 +,因为它很容易查看和理解,并且可以使代码不那么混乱。
如果您认为想要更改容器,或者您正在使用可能在各种容器类型上实例化的模板,请使用 advance,因为它适用于任何内容。
一般来说,我不担心更改容器类型,因为我发现当我确实必须更改容器类型时,我最终会重新访问使用该容器的所有地方,只是为了确保我没有这样做任何突然变得愚蠢的事情(比如从列表中间随机抽取元素)。
If you're never going to change the container (and you probably aren't), use + because it's easy to see and understand and leaves the code less cluttered.
If you think you want to change the container, OR if you are working inside a template that might be instantiated on various container types, use advance because it works with anything.
As a general rule, I don't worry about changing container types because I've found that when I do have to change a container type, I end up revisiting everywhere that container is used anyway, just to be sure I'm not doing anything that's suddenly stupid (like randomly plucking elements out of the middle of a list).
我在任何地方都使用 += 和 + ,因为它不会使代码混乱,并且任何如此特殊的迭代器也可以提供 += 和 + 运算符重载,因此从我的角度来看,关于泛型编程的争论实际上没有意义。
I use += and + everywhere because it doesn't clutter the code and any so special iterator could also provide += and + operator overloads so the argument about generic programming doesn't really make sense from my point of view.