Syntactic disambiguation using the template keyword
13.3 [temp.names]
John Spicer

Created on 1999-02-16.00:00:00 last changed 96 months ago


Date: 2010-08-15.00:00:00

[Voted into WP at August, 2010 meeting.]

Date: 2010-02-15.00:00:00

Proposed resolution (February, 2010):

Change 13.3 [temp.names] paragraph 5 as follows:

If a A name prefixed by the keyword template is not the name of a template, shall be a template-id or the name shall refer to a class template the program is ill-formed. [Note: the keyword template may not be applied to non-template members of class templates. —end note] [Note: as is the case with the typename prefix, the template prefix is allowed in cases where it is not strictly necessary; i.e., when the nested-name-specifier or the expression on the left of the -> or . is not dependent on a template-parameter, or the use does not appear in the scope of a template. —end note] [Example:

  template <class T> struct A {
    void f(int);
    template <class U> void f(U); };

  template <class T> void f(T t) {
    A<T> a;
    a.template f<>(t); // OK: calls template
    a.template f(t);   // error: not a template-id

  template <class T> struct B {template <class T2> struct C {}; };
  // OK: T::template C names a class template:
  template <class T, template <class X> class TT = T::template C> struct D {};
  D<B<int>> db;

end example]

Date: 2003-10-15.00:00:00

Notes from the October 2003 meeting:

We reviewed John Spicer's paper N1528 and agreed with his recommendations therein.

Date: 2000-04-15.00:00:00

Notes from 04/00 meeting:

The discussion of this issue revived interest in issues 11 and 109.

Date: 2001-03-27.00:00:00

The following is the wording from 13.3 [temp.names] paragraphs 4 and 5 that discusses the use of the "template" keyword following . or -> and in qualified names.

    When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (13.8.3 [temp.dep] ), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template. [Example:
        class X {
            template<std::size_t> X* alloc();
            template<std::size_t> static X* adjust();
        template<class T> void f(T* p) {
            T* p1 = p->alloc<200>();
                    // ill-formed: < means less than
            T* p2 = p->template alloc<200>();
                    // OK: < starts template argument list
                    // ill-formed: < means less than
            T::template adjust<100>();
                    // OK: < starts explicit qualification
    end example]

    If a name prefixed by the keyword template is not the name of a member template, the program is ill-formed. [Note: the keyword template may not be applied to non-template members of class templates. ]

The whole point of this feature is to say that the "template" keyword is needed to indicate that a "<" begins a template parameter list in certain contexts. The constraints in paragraph 5 leave open to debate certain cases.

First, I think it should be made more clear that the template name must be followed by a template argument list when the "template" keyword is used in these contexts. If we don't make this clear, we would have to add several semantic clarifications instead. For example, if you say "p->template f()", and "f" is an overload set containing both templates and nontemplates: a) is this valid? b) are the nontemplates in the overload set ignored? If the user is forced to write "p->template f<>()" it is clear that this is valid, and it is equally clear that nontemplates in the overload set are ignored. As this feature was added purely to provide syntactic guidance, I think it is important that it otherwise have no semantic implications.

I propose that paragraph 5 be modified to:

    If a name prefixed by the keyword template is not the name of a member template, or an overload set containing one or more member templates, the program is ill-formed. If the name prefixed by the template keyword is not followed by a template-argument-list, the program is ill-formed.

(See also issue 30 and document J16/00-0008 = WG21 N1231.)

Date User Action Args
2014-03-03 00:00:00adminsetstatus: fdis -> c++11
2011-04-10 00:00:00adminsetstatus: wp -> fdis
2010-11-29 00:00:00adminsetstatus: dr -> wp
2010-08-23 00:00:00adminsetmessages: + msg2921
2010-08-23 00:00:00adminsetstatus: ready -> dr
2010-03-29 00:00:00adminsetstatus: review -> ready
2010-02-16 00:00:00adminsetmessages: + msg2553
2010-02-16 00:00:00adminsetstatus: drafting -> review
2003-11-15 00:00:00adminsetmessages: + msg934
2003-04-25 00:00:00adminsetstatus: open -> drafting
2000-05-21 00:00:00adminsetmessages: + msg361
1999-02-16 00:00:00admincreate