Can anybody tell me how to increment the iterator by 2?
iter++
is available - do I have to do iter+2
? How can I achieve this?
http://www.cplusplus.com/reference/std/iterator/advance/
std::advance(it,n);
where n is 2 in your case.
The beauty of this function is, that If "it" is an random access iterator, the fast
it += n
operation is used (i.e. vector<,,>::iterator). Otherwise its rendered to
for(int i = 0; i < n; i++)
++it;
(i.e. list<..>::iterator)
If you don't have a modifiable lvalue of an iterator, or it is desired to get a copy of a given iterator (leaving the original one unchanged), then C++11 comes with new helper functions - std::next
/ std::prev
:
std::next(iter, 2); // returns a copy of iter incremented by 2
std::next(std::begin(v), 2); // returns a copy of begin(v) incremented by 2
std::prev(iter, 2); // returns a copy of iter decremented by 2
We can use both std::advance as well as std::next, but there's a difference between the two.
advance
modifies its argument and returns nothing. So it can be used as:
vector<int> v;
v.push_back(1);
v.push_back(2);
auto itr = v.begin();
advance(itr, 1); //modifies the itr
cout << *itr<<endl //prints 2
next
returns a modified copy of the iterator:
vector<int> v;
v.push_back(1);
v.push_back(2);
cout << *next(v.begin(), 1) << endl; //prints 2
If you don't know wether you have enough next elements in your container or not, you need to check against the end of your container between each increment. Neither ++ nor std::advance will do it for you.
if( ++iter == collection.end())
... // stop
if( ++iter == collection.end())
... // stop
You may even roll your own bound-secure advance function.
If you are sure that you will not go past the end, then std::advance( iter, 2 ) is the best solution.
Assuming list size may not be an even multiple of step you must guard against overflow:
static constexpr auto step = 2;
// Guard against invalid initial iterator.
if (!list.empty())
{
for (auto it = list.begin(); /*nothing here*/; std::advance(it, step))
{
// do stuff...
// Guard against advance past end of iterator.
if (std::distance(it, list.end()) > step)
break;
}
}
Depending on the collection implementation, the distance computation may be very slow. Below is optimal and more readable. The closure could be changed to a utility template with the list end value passed by const reference:
const auto advance = [&](list_type::iterator& it, size_t step)
{
for (size_t i = 0; it != list.end() && i < step; std::next(it), ++i);
};
static constexpr auto step = 2;
for (auto it = list.begin(); it != list.end(); advance(it, step))
{
// do stuff...
}
If there is no looping:
static constexpr auto step = 2;
auto it = list.begin();
if (step <= list.size())
{
std::advance(it, step);
}
The very simple answer:
++++iter
The long answer:
You really should get used to writing ++iter
instead of iter++
. The latter must return (a copy of) the old value, which is different from the new value; this takes time and space.
Note that prefix increment (++iter
) takes an lvalue and returns an lvalue, whereas postfix increment (iter++
) takes an lvalue and returns an rvalue.