It will only work if std::vector<int>::iterator
is an object type with operator++
a member function. If it's a scalar type (e.g. int *
), or operator++
is a non-member function, it will fail.
5.3.2 Increment and decrement [expr.pre.incr]
1 - The operand of prefix
++
is modified by adding1
[...]. The operand shall be a modifiable lvalue. [...]
2 - [...] The requirements on the operand of prefix--
[...] are [...] the same as those of prefix++
. [...]
Non-const non-static member functions can be called on temporary objects (since they have non-const
object type, per 9.3.2p3), but an lvalue reference parameter in a non-member function cannot bind to a temporary (13.3.3.1.4p3).
struct S { S &operator++(); };
struct T { }; T &operator++(T &);
typedef int U;
++S(); // OK
++T(); // fails
++U(); // fails
This means that it's nothing to do with the compiler, but rather the standard library; as you've observed libstdc++ is implemented with std::vector<int>::iterator
an object type with member operator++
, but your code could easily be compiled with the same compiler and a different standard library where std::vector<int>::iterator
is int *
, in which case it would fail.
std::vector
, std::array
and std::string
are the only container templates that can sensibly be implemented with scalar (pointer) iterators, but that doesn't mean that calling ++
on other containers' iterators is safe; they could have non-member operator++
as T
above.
To make an iterator to the before-the-end element, use std::prev
:
std::vector<int>::iterator it = std::prev(myVec.end());
std::prev
and std::next
are new in C++11, but are easily implementable in C++03.