ISO/ IEC JTC1/SC22/WG21 N0718

                                                 Document Number: WG21/N0718
                                                                  X3J16/95-0118
                                                 Date: 8 July 1995
                                                 Project: Programming Language C++
                                                 Reply to: Sean A. Corfield
                                                           sean@corf.demon.co.uk
 
                                        Templates and Special Member Functions
 
Abstract
        We have the facility to explicitly invoke a destructor inside a template
        for an arbitrary type (dependent on a template parameter), even if that
        type is in fact a builtin type.
 
        This raises the question of what other operations are, or should be,
        permitted and what other special member functions should be considered.
        This paper proposes that it should be possible to explicitly invoke the
        assignment operator and that it should be possible to take the address
        of the assignment operator.
 
Status quo & Rationale
        The following is currently well-formed:
 
                template<typename T> void f(T* p) {
                        p->~T();
                }
 
        regardless of the type with which 'f' is instantiated. The following is
        also well-formed:
 
                template<typename T> T& g(T& a, const T& b) {
                        return a = b;
                }
 
        for both builtin types and user-defined types (assuming the 'usual'
        definition of the assignment operator). However, an explicit invocation
        of the assignment operator is not well-formed for all types:
 
                template<typename T> T& g1(T& a, const T& b) {
                        return a.operator=(b);
                }
 
        This seems inconsistent. Furthermore, since the assignment operator is
        'just' another member function, it would seem reasonable to be able to
        write:
 
                template<typename T> void h(T& a, const T& b) {
                        T& (T::*pmf)(const T&) = &T::operator=;
                        (a.*pmf)(b);
                }
 
Proposal 1
        In the same way that explicit invocation of the destructor is allowed in
        templates for arbitrary types, explicit invocation of the assignment
        operator, using the functional form, should be permitted. I believe this
        should be non-controversial.
 
Proposal 2
        It should be possible to form a pointer to member for the assignment
        operator for arbitrary types. For builtin types, this would require the
        generation, by the compiler, of a trivial function that performed the
        assignment. I do not believe this would present significant difficulty
        for implementors, nor incur any overhead unless the instantiation
        required the address.
 
        Note: this assumes that it is currently possible to form the pointer to
        member for implicitly generated assignment operators for user-defined
        types -- I am not certain that this is the case, but if it is not, I
        believe it should be.
 
        This second proposal may in fact be editorial and/or already allowed
        by the WP.
 
WP changes 1
        In 12.8 [class.copy] (or perhaps 13.? [over.ass]) add the following
        wording:
 
                The notation for explicit call of a copy assignment operator can  be
                used  for  any scalar  type name.  [Note: allowing this makes it
                possible  to write  code  without having to know if an explicit
                assignment operator exists for a given type.  [Example:
                int* p;
                // ...
                p->operator=(0);
                --end example]  --end note]
 
 
WP changes 2
        It is not clear (to me, at least) whether this is already permitted
        by the wording in the WP.