Author: Doug Gregor <doug.gregor@gmail.com>
Document number: N3283=11-0053
Date: 2011-03-24
Dependent Bases and the Current Instantiation: Wording for Core Issue 1043
Proposed resolution:
Modify 14.2 [temp.names] paragraph 4 as follows:
- When the name of a member template specialization appears after
.
or ->
in a postfix-expression or after a nested-name-specifier in a qualified-id, and the object expression of the postfix-expression is type-dependent or the nested-name-specifier in the qualified-id depends on a template parameter (14.6.2 [temp.dep])refers to a dependent type, but the name is not does not refer to a member of the current instantiation (14.6.2.1 [temp.dep.type]), the member template name must be prefixed by the keyword template
. Otherwise the name is assumed to name a non-template.
Modify 14.6 [temp.res] paragraph 3 as follows:
- When a qualified-id is intended to refer to a type that is not a member of the current instantiation (14.6.2.1 [temp.dep.type]) and its nested-name-specifier depends on a template-parameter (14.6.2 [temp.dep])refers to a dependent type, it shall be prefixed by the keyword
typename
, forming a typename-specifier. If the qualified-id in a typename-specifier does not denote a type, the program is ill-formed.
Modify 14.6 [temp.res] paragraphs 6 and 7 as follows:
- If, for a given set of template arguments, a specialization of a template is instantiated that refers to a qualified-id that denotes a type, and the nested-name-specifier of the qualified-id depends on a template parameterqualified-id refers to a member of an unknown specialization, the qualified-id shall either be prefixed by
typename
or shall be used in a context in which it implicitly names a type as described above.
- Within the definition of a class template or within the definition of a member of a class template following the declarator-id, the keyword
typename
is not required when referring to the unqualified name of a previously declared member of the class template that declares a type. [Note: such names can be found using unqualified name lookup (3.4.1 [basic.lookup.unqual]), class member lookup (3.4.3.1 [class.qual]) into the current instantiation (14.6.2.1 [temp.dep.type]), or class member access expression lookup (3.4.5 [basic.lookup.classref]) when the type of the object expression is the current instantiation (14.6.2.2 [temp.dep.expr]). - end note]
Modify 14.6.2.1 [temp.dep.type] paragraphs 4 and 5 as follows:
- A name is a member of the current instantiation if it is
- An unqualified name that, when looked up, refers to at least one member of a class template the current instantiation or a non-dependent base class thereof. [Note: this can only occur when looking up a name in a scope enclosed by the definition of a class template. - end note ]
- A qualified-id in which the nested-name-specifier refers to the current instantiation and that, when looked up, refers to at least one member of the current instantiation or a non-dependent base class thereof. [Note: if no such member is found, and the current instantiation has any dependent base classes, then the qualified-id is a member of an unknown specialization; see below. - end note]
- An id-expression denoting the member in a class member access expression (5.2.5 [expr.ref]) for which the type of the object expression is the current instantiation, and the id-expression, when looked up (3.4.5 [basic.lookup.classref]), refers to at least one member of the current instantiation or a non-dependent base class thereof. [Note: if no such member is found, and the current instantiation has any dependent base classes, then the id-expression is a member of an unknown specialization; see below. - end note]
- A name is a member of an unknown specialization if it is
- the name is aA qualified-id in which the nested-name-specifier names a dependent type that is not the current instantiation.
- A qualified-id in which the nested-name-specifier refers to the current instantiation, the current instantiation has at least one dependent base class, and name lookup of the qualified-id does not find any member of the current instantiation or a non-dependent base class thereof.
- An id-expression denoting the member in a class member access expression (5.2.5 [expr.ref]) in which either
- the type of the object expression is the current instantiation, the current instantiation has at least one dependent base class, and name lookup of the id-expression does not find a member of the current instantiation or a non-dependent base class thereof; or
- the type of the object expression is dependent and is not the current instantiation.
Add the following new paragraphs after 14.6.2.1 [temp.dep.type] paragraph 5:
Modify 14.6.2.2 [temp.dep.expr] paragraph 5 as follows:
- A class member access expression (5.2.5 [expr.ref]) is type-dependent if the expression refers to a member of the current instantiation and the type of the referenced member is dependent, or the class member access expression refers to a member of an unknown specialization.
[ Note: in an expression of the form
x.y
or xp->y
the type of the expression is usually the type of the member y
of the class of x
(or the class pointed to by xp
). However, if x
or xp
refers to a dependent type that is not the current instantiation, the type of y
is always dependent. If x
or xp
refers to a non-dependent type or refers to the current instantiation, the type of y
is the type of the class member access expression. - end note ]
Modify 14.6.2.4 [temp.dep.temp] paragraph 4 as follows:
- A template template-argument is dependent if it names a template-parameter or is a qualified-id with a
nested-name-specifier which contains a class-name or a decltype-specifier that denotes a dependent typethat refers to a member of an unknown specialization.