Re: Validity of references returned from iterators

Discussion in 'C++' started by James Kanze, Jul 31, 2013.

  1. James Kanze

    James Kanze Guest

    On Wednesday, 31 July 2013 06:07:09 UTC+1, Christopher Head wrote:

    > I was in the process of writing an STL-style iterator class. I grabbed
    > N3337 (as I don’t have access to the actual standard) and looked at the
    > requirements for the various iterator types. I couldn’t seem to find,
    > anywhere, the rules describing over what period of time pointers and
    > references returned from iterators are valid. That is to say, given
    > this code:

    > template<typename Titer> void f(Titer iter) {
    > T &elt = *iter;
    > // Do something with iter
    > elt.do_something();
    > }

    > what are the things I am allowed to do in the commented line and expect
    > elt to still be a useful reference to the same element it initially
    > pointed to?

    > For the standard STL containers, of course, the answer is easy: I’m
    > allowed to do pretty much anything with iter, because elt points to an
    > object in the underlying container which has nothing to do with the
    > iterator.

    > I did find this sentence in [iterator.requirements.general]:
    > “Destruction of an iterator may invalidate pointers and references
    > previously obtained from that iterator.”

    > That’s all well and good, but I couldn’t find *any* other cases which
    > were documented as allowed to invalidate said pointers and references.

    > If Titer were istream_iterator, for example, then doing “++iter” would
    > be bad: using elt is, if I understand correctly, undefined behaviour in
    > that case. Now, I know that istream_iterator is an input iterator and I
    > know that input iterators specify that after invoking ++r, any copies
    > of the old value of r are no longer required to be dereferenceable. OK,
    > but that doesn’t actually say anything about the validity of elt, which
    > was initialized back when iter *was* dereferenceable—and iter, the
    > iterator from which elt was initialized, certainly hasn’t been
    > destroyed, so the sentence I pasted from general requirements doesn’t
    > apply!

    > My question is thus: what are the rules, and where in the standard are
    > they defined?

    The simple answer is that there aren't any rules; each iterator
    defines its own rules. And they often involve things other than
    the iterator: insert or erase on a container can invalidate
    iterators, references or pointers into the container, for
    example. Destruction or modification of the iterator can
    invalidate the reference (but only for InputIterator, if
    I recall correctly). And so on. If you design your own
    iterator, you set the rules. If you write a template function
    which takes an iterator as a template argument, you specify the
    minimum rules that iterator has to adhere to, and so on.

    James Kanze, Jul 31, 2013
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. falcon
  2. Marcin Kaliciñski

    Iterators and reverse iterators

    Marcin Kaliciñski, May 8, 2005, in forum: C++
    Kai-Uwe Bux
    May 8, 2005
  3. , India
    James Kanze
    Aug 8, 2009
  4. Öö Tiib
    Öö Tiib
    Jul 31, 2013
  5. Christopher Head
    Christopher Head
    Aug 11, 2013

Share This Page