1

I need to iterate over some elements in backward order and I'm using:

for ( /* ... */ it = vec.end() - 1, end = vec.begin() ; it >= end ; --it ) {
    // ...

I now that end() - 1 is defined for some containers, including vector, but now I need to know if begin decrement is also defined.

EDIT

I don't know if I could use reverse_iterator, because I'll need to pass these iterators as parameters to std::vector::erase and from the documentation, it looks that they are different types.

Community
  • 1
  • 1
vinipsmaker
  • 2,215
  • 2
  • 19
  • 33

2 Answers2

15

Yes, it is undefined.

If you want to iterate over elements in reverse, just use rbegin and rend. They're reverse iterators, designed explicitly for this purpose. If you need to get a standard iterator from the reverse iterator, you can use the base member function on the iterator.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • I don't know if I could use reverse_iterator, because I'll need to pass these iterators as parameters to std::vector::erase and from the documentation, it looks that they are different types. – vinipsmaker Aug 14 '13 at 08:02
  • Thank you. It looks like that I'll leave UB land. :) – vinipsmaker Aug 14 '13 at 20:30
4

It is undefined behaviour. But why not use reverse iterators rbegin() and rend()?

std::vector<int> vec{0,1,2,3,4}
for (auto it = vec.rbegin(); it != vec.rend(); ++it) 
{
  std::cout << *it << " ";
}
std::cout << std::endl;

output

4 3 2 1 0

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • I don't know if I could use reverse_iterator, because I'll need to pass these iterators as parameters to std::vector::erase and from the documentation, it looks that they are different types – vinipsmaker Aug 14 '13 at 08:01
  • @vinipsmaker you should probably not be calling erase inside an iterator loop anyway. Maybe you should explain what you are trying to achieve. If it is too different from just iterating backwards, then it should be a different question. – juanchopanza Aug 14 '13 at 08:03
  • if I can decrement begin, problem is solved. It looks, from the other question, that this behaviour is undefined, but there a lot of reasons why this must work, unless compiler wants to put an `if` to bug code relying on this behaviour and, together with this `if`, unnecessarily killing performance. – vinipsmaker Aug 14 '13 at 08:06
  • PS.: And reverse iteration is required, because iterators to elements beyond the removed range are invalidated. – vinipsmaker Aug 14 '13 at 08:07
  • 1
    @vinipsmaker there are no special `if` required, and you can typically type `--begin()`. For e.g. for `std::vector` it will simply do a pointer decrement). However, even for a C-array, pointing to one-before-the-beginning is undefined behavior, even without dereferencing. Undefined behavior includes that your code will work, except e.g. when you give a live demo :-) – TemplateRex Oct 11 '13 at 19:50