This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 110c. See for the official list.


96. Syntactic disambiguation using the template keyword

Section: 13.3  [temp.names]     Status: C++11     Submitter: John Spicer     Date: 16 Feb 1999

[Voted into WP at August, 2010 meeting.]

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.

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:

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

Notes from 04/00 meeting:

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

Notes from the October 2003 meeting:

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

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]