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
    James Kanze, Jul 31, 2013
    #1
    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
    Replies:
    4
    Views:
    508
  2. Marcin Kaliciñski

    Iterators and reverse iterators

    Marcin Kaliciñski, May 8, 2005, in forum: C++
    Replies:
    1
    Views:
    472
    Kai-Uwe Bux
    May 8, 2005
  3. , India
    Replies:
    10
    Views:
    1,053
    James Kanze
    Aug 8, 2009
  4. Öö Tiib
    Replies:
    0
    Views:
    177
    Öö Tiib
    Jul 31, 2013
  5. Christopher Head
    Replies:
    0
    Views:
    143
    Christopher Head
    Aug 11, 2013
Loading...

Share This Page