5

I'm just learning STL and reverse_iterator has me confused. It has a default constructor but I don't understand how to use it. I tried:

reverse_iterator<int*> r{};
r --;

and the program crashed. I believe there is no point to this usage and it can easily cause a crash, so why is the default constructor allowed to be used?

3
  • 2
    Probably just to support declaring "uninitialized" iterators to be assigned a specific value later. Just treat default-constructed iterators as uninitialized variables, i.e. don't do anything with them until you assign a meaningful value. Commented Sep 17, 2017 at 16:07
  • Why are you allowed to define a pointer that points to nullptr and then dereference it? There are lots of things that are allowed that are very unsafe, undefined even. It's what gives C++ it's speed and it's shoot-yourself-in-the-foot status. Commented Sep 17, 2017 at 16:07
  • @RickAstley I believe the C++ standard library have moved from the "shoot feet at will" mentality to "you won't shoot your feet if it costs nothing". There would have to have further reasons if something unsafe were allowed Commented Sep 17, 2017 at 16:08

2 Answers 2

3

std::reverse_iterator are bidirectional iterators, which have a distinct requirement that they be default-constructible.

As to why bidirectional iterators are default-constructible, it is mostly because it is almost certain they are trivial to implement and giving guarantees like this makes algorithms easier to implement.

Writing things like int* p = nullptr; *p; is itself UB, it violates the precondition that p be dereferenceable, letting adaptors "adopt" these kinds of behaviour is rather natural.

Sign up to request clarification or add additional context in comments.

Comments

3

The documentation on cppreference says:

1) Default constructor. current is value-initialized. Operations on the resulting iterator have defined behavior if and only if the corresponding operations on a value-initialized Iterator also have defined behavior.

There are some iterators that are meaningful to be default constructed; usually not those that directly associated with containers (that I'm aware of). For example an istream iterator: http://en.cppreference.com/w/cpp/iterator/istream_iterator/istream_iterator. However, it's not bidirectional so you can't reverse it.

However, in principle, you could have an iterator that is both bidirectional, and whose default constructor/value initializer has at least some operations defined. For such an iterator, you'd want the behavior to be reflected through the reverse_iterator.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.