ISO/ IEC JTC1/SC22/WG21 N0719

                                                 Document Number: WG21/N0719
                                                                  X3J16/95-0119
                                                 Date: 8 July 1995
                                                 Project: Programming Language C++
                                                 Reply to: Sean A. Corfield
                                                           sean@corf.demon.co.uk
 
                                        operator->() revisited
 
Abstract
        The checking of the return type of operator->() declared within a template
        is deferred to the point of use (to enable pointer-like template classes
        to be written for arbitrary types). The STL introduced iterators into the
        standard library and these have pointer-like behaviour with the notable
        omission of operator->(). Furthermore, the restrictions on the return type
        would not seem to need to apply to explicit invocations of operator-> since
        such invocations do not require a member name.
 
        This paper proposes that the iterators defined in the standard library
        provide operator->() where it is appropriate to do so. This paper also
        proposes that the return type restriction be revised in general to be
        applied only at the point of use for the implicit invocation in x->m.
 
        The paper is in two independent parts.
 
Part 1 - iterators and operator->()
        This relates to clause 24 issue 10 in N0702 = 95-0102.
 
Discussion
        What does operator->() mean for input and output iterators? For practical
        purposes, the uses would be as follows:
 
                x = it->m;
                it->m = y;
 
        In current terms these would be equivalent to:
 
                x = (*it).m;
                (*it).m = y;
 
        It seems reasonable that the former be valid exactly when the latter are
        and have exactly the same semantics. For output iterators, it is not clear
        how a member only can be assigned, so this proposal leaves that issue open
        (as in the issues list N0702 = 95-0102).
 
Proposal
        Add operator->() to the requirements for all iterators except output
        iterators.
 
Rationale
        Programmers will expect operator-> to be defined for pointer-like objects
        which iterators claim to be. For output iterators, we can argue that it is
        the entire referenced object which acts as the sink and allowing operator->
        would lead to partially uninitialised objects -- this would seem to be
        undesirable. Under the current semantics, '(*out_it).m = x;' does not
        make sense anyway.
 
WP changes
        In 24.1 [lib.iterator.requirements], after:
 
                All iterators i support the expression *i,
                resulting in a value of some class, enumeration, or built-in  type  T,
                called  the value type of the iterator.
 
        Add:
 
                All iterators i for which the expression (*i).m is well-formed support
                the expression i->m with the same semantics as (*i).m.
 
        In the requirements table for input iterators, add:
 
                a->m    T     return (*i).m   pre: (*i).m is well-formed and has type T
 
        (Should a different type to 'T' be used here?)
 
        [Note: output iterators do not require operator-> to be defined]
 
        In the requirements table for forward iterators, add:
 
                a->m    T&    return (*i).m   pre: (*i).m is well-formed and has type T
 
        (because the expression (*i).m cannot have reference type).
 
        In 24.3.1.1 [lib.reverse.bidir.iter], in the declaration of the template
        class reverse_bidirectional_iterator, add the following member declaration:
 
                T*      operator->();
 
        After 24.3.1.2.3 [lib.reverse.bidir.iter.op.star] add a new sub-clause
        [lib.reverse.bidir.iter.op.points] with the following text:
 
                        T* operator->();
 
                Effects:
                        BidirectionalIterator tmp = current;
                        return (--tmp).operator->();
 
Part 2 - relaxing the restrictions on the return type of operator->()
        Note in the above WP changes that defining operator->() for the reverse
        bidirectional iterator uses the explicit invocation of the function called
        operator-> on the adapted iterator. There is no reason why this would not
        be appropriate in other situations too. There is also no reason why the
        return type of operator->() should be constrained to be a pointer to class
        type in these situations.
 
Proposal
        Relax the restriction on the return type of operator->() so that checking
        is performed only for the implicit use in expressions such as x->m for both
        the template and non-template case.
 
WP changes
        Delete 14.3.3 [temp.opref].
 
        In 13.5.6 [over.ref], paragraph 1, delete:
 
                operator->  shall return either a pointer to a
                class or an object of or a reference to a class for  which  operator->
                is  defined,  except  in  some cases when it is a member of a template
                (see _temp.opref_).  T::operator-> shall not return an  object  of  or
                reference to its own class type T.
 
        Since 5.2.4 [expr.ref] already has restrictions on the lhs of ->, no
        further changes are required.