简体   繁体   中英

Advance iterator for the std::vector std::advance VS operator +?

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 ?

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, but std::advance keeps your code more generic (eg you could substitute a list for the vector , and that part would still work).

For those who care, the standard describes advance and distance as follows (§24.3.4/1):

Since only random access iterators provide + and - operators, the library provides two function templates advance and distance . These function templates use + and - for random access iterators (and are, therefore, constant time for them); for input, forward and bidirectional iterators they use ++ to provide linear time implementations.

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 (and std::prev similarly). The difference from std::advance is that it returns the modified iterator (which std::advance doesn't), which can be convenient in some cases.

That depends on what you need:

If you need genericity , use std::advance(it,2) . If someone comes along and changes your std::vector into a std::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 your std::vector into a std::list , the code will fail to compile, pointing (maybe with a helpful comment) at a serious performance issue.

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 (eg a forward iterator, or a bidirectional iterator), then you can use std::advance , but it's slower because it actually walks across all of the intermediate elements.

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

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 from std::vector ) and will increase iterator in loop for ForwardAccessIterator (as like one in std::list ).

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.

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM