Created on 2009-11-19.00:00:00 last changed 130 months ago
[Voted into the WP at the March, 2011 meeting as part of paper N3262.]
Proposed resolution (November, 2010) [SUPERSEDED]:
Change 13.8.2 [temp.local] paragraphs 1-5 as follows:
Like normal (non-template) classes, class templates have an injected-class-name (Clause 11 [class]). The injected-class-name can be used
with or without a template-argument-listas a template-name or a type-name.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, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration it refers to thespecified class template specialization, which could be the current specialization or another specialization.class template itself. Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.Within the scope of a class template specialization or partial specialization, when the injected-class-name is not
followed by a <used as a type-name, it is equivalent to theinjected-class-nametemplate-name followed by the template-arguments of the class template specialization or partial specialization enclosed in <>. [Example:template<template<class> class T> class A { }; template<class T> class Y; template<> class Y<int> { Y* p; // meaning Y<int> Y<char>* q; // meaning Y<char> A<Y>* a; // meaning A<::Y> class B { template<class> friend class Y; // meaning ::Y }; };—end example]
The injected-class-name of a class template or class template specialization can be used either
with or without a template-argument-listas a template-name or a type-name 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> }; template<class T, template<class> class U = T::template Base> struct Third { }; Third<Base<int>> t; // OK, default argument uses injected-class-name as a template—end example]
A lookup that finds an injected-class-name (6.5.2 [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-listused as a template-name, 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; // OK };—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 always refers to the class template itself and not a specialization of the template. [Example:...
This resolution also resolves issue 602.
The injected-class-name of a class template can be used either by itself, in which case it is a type denoting the current instantiation, or followed by a template argument list, in which case it is a template-name. It would be helpful to extend this treatment so that the injected-class-name could be used as an argument for a template template parameter:
template <class T> struct A { }; template <template <class> class TTP> struct B { }; struct C: A<int> { B<A> b; };
(This is accepted by g++.)
James Widman:
It would not be so helpful when used with overloaded function templates, for example:
template <template <class> class TTP> void f(); // #1 template < class T > void f(); // #2 template <class T> struct A { }; struct C: A<int> { void h( ) { f<A>(); // #1? #2? Substitution failure? } };
(See also issue 602.)
History | |||
---|---|---|---|
Date | User | Action | Args |
2014-03-03 00:00:00 | admin | set | status: fdis -> c++11 |
2011-04-10 00:00:00 | admin | set | messages: + msg3391 |
2011-04-10 00:00:00 | admin | set | status: review -> fdis |
2010-11-29 00:00:00 | admin | set | messages: + msg3106 |
2010-11-29 00:00:00 | admin | set | status: drafting -> review |
2010-08-23 00:00:00 | admin | set | status: open -> drafting |
2009-11-19 00:00:00 | admin | create |