Doc. No.: WG21/N1896, J16/05-0156
Date: 2005-10-13
Reply to: Clark Nelson
Phone: +1-503-712-8433
Email: clark.nelson@intel.com

Proposed resolution of core issue 301 (revision 1)

Primary changes for operator function templates

The principle behind these proposed edits is to change the definition of template-id to include operator-function-id cases. simple-template-id is introduced as an equivalent to the previous template-id, where the name of the template is restricted to an identifier.

  1. Change the definition of operator-function-id (13.5p1):

    operator-function-id:
    operator operator
    operator operator < template-argument-listopt >

    This undoes the grammar change that was made for core issue 38.

  2. Rename template-id to simple-template-id, and add a new definition for template-id (14.2p1):

    simple-template-id:
    template-name < template-argument-listopt >
    template-id:
    simple-template-id
    operator-function-id < template-argument-listopt >
  3. Change 13.5p1:

    A function declaration having one of the following operator-function-ids as its name declares an operator function. A function template declaration having one of the following operator-function-ids as its name declares an operator function template. A specialization of an operator function template is also an operator function. An operator function is said to implement the operator named in its operator-function-id.

  4. Change 14.2p3:

    After name lookup (3.4) finds that a name is a template-name, or that an operator-function-id refers to a set of overloaded functions any member of which is a function template, if this name is followed by a <, the < is always taken as the beginning delimiter of a template-argument-list and never as a name followed by the less-than operator. When parsing a template-id template-argument-list, the first non-nested >131) is taken as the end of the template-argument-list ending delimiter rather than a greater-than operator.

Secondary changes: references to template-id which should be to simple-template-id

References from the grammar are presented first.

  1. Change the definition of nested-name-specifier (5.1p7):

    nested-name-specifier:
    type-name ::
    namespace-name ::
    nested-name-specifier identifier ::
    nested-name-specifier templateopt simple-template-id ::
  2. Change the definition of pseudo-destructor-name (5.2p1):

    pseudo-destructor-name:
    ::opt nested-name-specifieropt type-name :: ~ type-name
    ::opt nested-name-specifier template simple-template-id :: ~ type-name
    ::opt nested-name-specifieropt ~ type-name
  3. Change the definition of simple-type-specifier (7.1.5.2p1):

    simple-type-specifier:
    ::opt nested-name-specifieropt type-name
    ::opt nested-name-specifier template simple-template-id
    char
    wchar_t
    bool
    short
    int
    long
    signed
    unsigned
    float
    double
    void
  4. Change the definition of elaborated-type-specifier (7.1.5.3):

    elaborated-type-specifier:
    class-key ::opt nested-name-specifieropt identifier
    class-key ::opt nested-name-specifieropt templateopt simple-template-id
    enum ::opt nested-name-specifieropt identifier
  5. Change the definition of class-name (9p1):

    class-name:
    identifier
    simple-template-id
  6. Change the definition of class-head (9p1):

    class-head:
    class-key identifieropt base-clauseopt
    class-key nested-name-specifier identifier base-clauseopt
    class-key nested-name-specifieropt simple-template-id base-clauseopt
  7. Change the definition of typename-specifier (14.6p3):

    typename-specifier:
    typename ::opt nested-name-specifier identifier
    typename ::opt nested-name-specifier templateopt simple-template-id
  8. Change 3.3.1p3:

    The point of declaration for a class first declared by a class-specifier is immediately after the identifier or simple-template-id (if any) in its class-head (Clause 9). The point of declaration for an enumeration is immediately after the identifier (if any) in its enum-specifier (7.2).

  9. Change 3.4.5p6:

    If the nested-name-specifier contains a class template-id simple-template-id (14.2), the names in its template-arguments are evaluated looked up in the context in which the entire postfix-expression nested-name-specifier occurs.

  10. Change the grammar-like portion of 7.1.5.3p1:

    class-key identifier ;
    friend class-key ::opt identifier ;
    friend class-key ::opt simple-template-id ;
    friend class-key ::opt nested-name-specifier identifier ;
    friend class-key ::opt nested-name-specifier templateopt simple-template-id ;
  11. Change 14.2p6:

    A simple-template-id that names a class template specialization is a class-name (clause 9).

  12. Change the first sentence of 14.5.4p1:

    A primary class template declaration is one in which the class template name is an identifier. A template declaration in which the class template name is a simple-template-id, is a partial specialization of the class template named in the simple-template-id. ...

  13. Change the last bullet of 14.6.2.1p6:

    a simple-template-id in which either the template name is a template parameter or any of the template arguments is a dependent type or an expression that is type-dependent or value-dependent.

  14. Change 14.7p3:

    An explicit specialization may be declared for a function template, a class template, a member of a class template or a member template. An explicit specialization declaration is introduced by template<>. In an explicit specialization declaration for a class template, a member of a class template or a class member template, the name of the class that is explicitly specialized shall be a simple-template-id. In the explicit specialization declaration for a function template or a member function template, the name of the function or member function explicitly specialized may be a template-id.

  15. Change 14.7.3p9:

    A simple-template-id that names a class template explicit specialization that has been declared but not defined can be used exactly like the names of other incompletely-defined classes (3.9).

  16. Change the last bullet of 14.8.2.1p4:

    If P is a class, and P has the form simple-template-id, then A can be a derived class of the deduced A. Likewise, if P is a pointer to a class of the form simple-template-id, A can be a pointer to a derived class pointed to by the deduced A.

Other secondary changes

  1. Change 3.4.3.1p1, third bullet:

    the names in a template-argument of a template-id are looked up in the context in which the entire postfix-expression qualified-id occurs.

    This is just editorial clarification.

  2. Change 3.4.3.2p1:

    If the nested-name-specifier of a qualified-id nominates a namespace, the name specified after the nested-name-specifier is looked up in the scope of the namespace, except that the names in a template-argument of a template-id are looked up in the context in which the entire postfix-expression qualified-id occurs.

    This is just editorial clarification.

  3. Change 14p2:

    A template-declaration can appear only as a namespace scope or class scope declaration. In a function template declaration, the last component of the declarator-id shall be a template-name or operator-function-id (i.e., not a template-id). [ Note: in a class template declaration, if the class name is a simple-template-id, the declaration declares a class template partial specialization (14.5.4). —end note ]

  4. Change 14.7.2p2:

    If the explicit instantiation is for a class, a function or a member template specialization, If the explicit instantiation is for a class or member class, the elaborated-type-specifier in the declaration shall include a simple-template-id. If the explicit instantiation is for a function or member function, the unqualified-id in the declaration shall be either a template-id or, where all template arguments can be deduced, a template-name or operator-function-id. [ Note: the declaration may declare a qualified-id, in which case the unqualified-id of the qualified-id must be a template-id. —end note ] If the explicit instantiation is for a member function, a member class or a static data member of a class template specialization, the name of the class template specialization in the qualified-id for the member name shall be a simple-template-id. An explicit instantiation shall appear in an enclosing namespace of its template. If the name declared in the explicit instantiation is an unqualified name, the explicit instantiation shall appear in the namespace where its template is declared. [ Note: regarding qualified names in declarators, see 8.3. —end note ]

    The problem here is that in an explicit instantiation of a class (or member class), there is no unqualified-id, at least not at the top level. So I broke out the class case separately from the function case. Note also an added reference to simple-template-id.