That is, providing that container
is not empty, can I safely do this:
std::vector<int> container;
container.push_back( 0xFACE8D );
auto last = container.end() - 1;
and this:
EDIT: replaced -1
with --
here:
std::list<int> container;
container.insert( 0xFACE8D );
auto last = container.end();
--last;
and again for arbitrary non-empty container?
EDIT: let me clarify the question.
Sometimes perfectly legal code behaves incorrectly. The question is: assuming that the above code compiles, is it safe to do something like that?
It should be safe for ordinary C-style arrays because the corresponding iterators are just pointers. But is it safe for more complicated containers?
Suppose that one implements list with iterators like this one:
class MyListIterator {
MyListIterator *prev, *next;
MyListIterator * operator--() { return prev; }
...
};
class MyList {
MyListIterator *end() { return NULL; }
...
};
Then an attempt to decrement container::end()
, despite being perfectly legal syntactically, would cause a segfault.
I hope, though, that stl
containers are much smarter than that. Thus the question on the guarantees on the above stl::list
code behavior, if any.
std::vector
returns random-access iterators, so yes, this is safe with vector
.
std::list
returns bidirectional iterators. They can be incremented (++
) and decremented (--
), but don't allow for arbitrary arithmetic (+
, -
) or relative comparisons (>
, <
). It's not safe with list
.
You can use std::advance
on bidirectional iterators to advance or rewind arbitrary amounts. In C++11 you can use std::prev
in place of iter - 1
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With