Iterator Reduction

I have a normal iterator in position in a bidirectional data structure (actually actually). Now I want to perform an operation on the past x elements from my current position. There will always always be at least x elements, although the last x may be the first element of the vector.

I wrote this code

vector<Record>::iterator it = itCurrentRecord; for (unsigned int i = 0; i < length; i++) { (it--)->length = length; } 

It is safe? I am worried that when it points to the first element, the last decrement will cause the iterator to point to one before the first element, which is invalid.

If so, how can I rewrite this in a safe way?

thanks

+6
source share
4 answers

Use the reverse iterator:

 vector<Record>::reverse_iterator it = itCurrentRecord; for (unsigned int i = 0; i < length; i++) { (it++)->length = length; } 

which allows you to semantically indicate one-to-start, like a regular iterator, it is allowed to indicate one end.

+13
source

Your concern is indeed. Since this is a random access iterator, you can use arithmetic to avoid undefined behavior:

 vector<Record>::iterator it = itCurrentRecord; for (unsigned int i = 0; i < length; i++) { (it - i)->length = length; } 
+3
source

You can run it at the beginning of the range and iterate forward.

 vector<Record>::iterator it = std::prev(itCurrentRecord, length - 1); for (unsigned int i = 0; i < length; i++) { (it++)->length = length; } 

Note. std::prev is a C ++ 11 function.

0
source

In addition to the solutions already mentioned, you can do something like:

 // assume vector<Record> v is filled; vector<Record>::iterator it = currentRecord; for_each(v.begin(), it, [&](Record& r) { r.length = length; }); 

Or, if you need / want to go back (for example, if the iteration order matters):

 for_each(reverse_iterator<vector<Record>::iterator>(it), v.rend(), [&](Record& r) { r.length = length; }); 
0
source

Source: https://habr.com/ru/post/954270/


All Articles