Home > other >  Subtracting 1 vs decrementing an iterator
Subtracting 1 vs decrementing an iterator

Time:10-07

In the accepted answer to "Iterator to last element of std::vector using end()--" @barry states:

Note that if vector::iterator is just T* (which would be valid), the first form above is ill-formed. The second two work regardless, so are preferable.

referring to his code:

std::vector<int>::iterator it = --container.end();
std::vector<int>::iterator it = container.end() - 1;
std::vector<int>::iterator it = std::prev(container.end());

This opinion is disputed in the comments, however without a clear resolution. So that's my question: what exactly is the semantic difference between the first and the second? And would the answer be different for iterators over structures other than vector?

CodePudding user response:

For any standard library container, the member function end() returns an r-value. It's a "temporary" until you assign it to a variable.

The decrement operator -- is not required to work on r-value iterators. You would be modifying a temporary, which C historically has taken measures to avoid.

Therefore, --container.end() might compile on your standard-conforming C compiler. But it might not.

std::prev(container.end()) will work on every standard-conforming compiler.


To review:

  • --container.end() may not compile. It is up to the implementation.
  • container.end() - 1 will only compile if the container uses random-access iterators.
  • std::prev(container.end()) will always compile.

All three forms will produce the same result, if they compile.

  • Related