Document number:  00-0026/N1249
Date:  April 19, 2000
Author:  John Spicer, Edison Design Group
 jhs@edg.com

Drafting from Tokyo Meeting - Revision 2

Introduction

This document contains the proposed wording for the changes in the standard associated with the following issues from the core issues list.

  1. 176. Name injection and class templates.
  2. 183. Use of typename in explicit specializations.
  3. 206. Semantic constraints on nondependent names
  4. 213. Lookup in dependent base classes.
  5. 217. Default arguments for member functions of class templates.

176. Name injection and class templates.

Note: These changes depend on the changes for issue 147 ("Naming the Constructor"), which is currently in "ready" status.

In 14.6.1p1, replace

Within the scope of a class template, when the name of the template is neither qualified nor followed by <, it is equivalent to the name of the template followed by the template-parameters enclosed in <>. [Example: the constructor for Set can be referred to as Set() or Set<T>(). ] Other specializations (_temp.expl.spec_) of the class can be referred to by explicitly qualifying the template name with the appropriate template-arguments. [Example:

template<class T> class X { X* p; // meaning X<T> X<T>* p2; X<int>* p3; }; --end example]

Within the scope of a class template specialization or partial specialization, when the name of the template is neither qualified nor followed by <, it is equivalent to the name of the template followed by the template-arguments enclosed in <>.

With

Like normal (non-template) classes, class templates have an injected-class-name. The injected-class-name can be used with or without a template-argument-list. When it is used without a template-argument-list it is equivalent to the injected-class-name followed by the template-parameters of the class template enclosed in <>. When it is used with a template-argument-list it refers to the specified class template specialization, which could be the current specialization or another specialization.

Within the scope of a class template specialization or partial specialization, when the injected-class-name is not followed by a <, it is equivalent to the injected-class-name followed by the template-arguments of the class template specialization or partial specialization enclosed in <>. [Example:

template<class T> class Y; template<> class Y<int> { Y* p; // meaning Y<int> Y<char>* q; // meaning Y<char> }; --end example]

The injected-class-name of a class template or class template specialization can be used either with or without a template-argument-list wherever it is in scope. [Example:

template <class T> struct Base { Base *p; }; template <class T> struct Derived : public Base<T> { typename Derived::Base* p; // meaning Derived::Base<T> }; --end example]

A lookup that finds an injected-class-name (class.member.lookup) can result in an ambiguity in certain cases (for example, if it is found in more than one base class). If all of the injected-class-names that are found refer to specializations of the same class template, and if the name is followed by a template-argument-list, the reference refers to the class template itself and not a specialization thereof, and is not ambiguous. [Example:

template <class T> struct Base {}; template <class T> struct Derived : Base<int>, Base<char> { typename Derived::Base b; // error: ambiguous typename Derived::Base<double> d; // okay }; --end example]

When the normal name of the template (i.e., the name from the enclosing scope, not the injected-class-name) is used without a template-argument-list it refers to the class template itself and not a specialization of the template. [Example:

template<class T> class X { X* p; // meaning X<T> X<T>* p2; X<int>* p3; ::X* p4; // error: missing template argument list // ::X does not refer to the injected-class-name }; --end example]

183. Use of typename in explicit specializations.

In 14.6p5, replace

The keyword typename shall only be applied to qualified names, but those names need not be dependent.

With

The keyword typename shall be applied only to qualified names, but those names need not be dependent. The keyword typename shall be used only in contexts in which dependent names can be used. This includes template declarations and definitions but excludes explicit specialization declarations and explicit instantiation declarations.

206. Semantic constraints on nondependent names

In 14.6p7 after the following text

Knowing which names are type names allows the syntax of every template definition to be checked. No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.
Add the following
If a type used in a non-dependent name is incomplete at the point at which a template is defined but is complete at the point at which an instantiation is done, and if the completeness of that type affects whether or not the program is well-formed or affects the semantics of the program, the program is ill-formed; no diagnostic is required.

213. Lookup in dependent base classes.

In 14.6.2p3, replace

In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, if a base class of this template depends on a template-parameter, the base class scope is not examined during name lookup until the class template is instantiated.
With
In the definition of a class template or a member of a class template, if a base class of the class template depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.

Remove from 14.6.2p4

If a base class is a dependent type, a member of that class cannot hide a name declared within a template, or a name from the template's enclosing scopes.

217. Default arguments for member functions of class templates.

In 8.3.6p6, replace

The default arguments in a member function definition that appears outside of the class definition are added to the set of default arguments provided by the member function declaration in the class definition.

With

Except for member functions of class templates, the default arguments in a member function definition that appears outside of the class definition are added to the set of default arguments provided by the member function declaration in the class definition. Default arguments for a member function of a class template must be specified on the initial declaration of the member function within the class template.

End of document.