Стандарт C++ 11 (1119564), страница 98
Текст из файла (страница 98)
In the case of a non-type template argument, the argument must have been giventhe value of the template parameter and not an expression in which the template parameter appears as asubexpression. [ Example:template <class T> class A {A* p1;A<T>* p2;A<T*> p3;::A<T>* p4;class B {B* p1;A<T>::B* p2;typename A<T*>::B* p3;////////A is the current instantiationA<T> is the current instantiationA<T*> is not the current instantiation::A<T> is the current instantiation////////B is the current instantiationA<T>::B is the current instantiationA<T*>::B is not thecurrent instantiation};};template <class T> class A<T*> {A<T*>* p1;// A<T*> is the current instantiationA<T>* p2;// A<T> is not the current instantiation};template <class T1, class T2, int I> struct B {B<T1, T2, I>* b1;// refers to the current instantiationB<T2, T1, I>* b2;// not the current instantiationtypedef T1 my_T1;static const int my_I = I;static const int my_I2 = I+0;static const int my_I3 = my_I;B<my_T1, T2, my_I>* b3;// refers to the current instantiationB<my_T1, T2, my_I2>* b4;// not the current instantiationB<my_T1, T2, my_I3>* b5;// refers to the current instantiation};— end example ]4A 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 the current instantiationor a non-dependent base class thereof.
[ Note: This can only occur when looking up a name in a scopeenclosed 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, whenlooked up, refers to at least one member of the current instantiation or a non-dependent base classthereof.
[ Note: if no such member is found, and the current instantiation has any dependent baseclasses, 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) for which the typeof the object expression is the current instantiation, and the id-expression, when looked up (3.4.5),§ 14.6.2.1360© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)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 theid-expression is a member of an unknown specialization; see below.
— end note ][ Example:template <class T> class A {static const int i = 5;int n1[i];// i refers to a member of the current instantiationint n2[A::i];// A::i refers to a member of the current instantiationint n3[A<T>::i]; // A<T>::i refers to a member of the current instantiationint f();};template <class T> int A<T>::f() {return i;// i refers to a member of the current instantiation}— end example ]5A name is a member of an unknown specialization if it is— A qualified-id in which the nested-name-specifier names a dependent type that is not the currentinstantiation.— 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 anymember 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) in which either— the type of the object expression is the current instantiation, the current instantiation has at leastone dependent base class, and name lookup of the id-expression does not find a member of thecurrent instantiation or a non-dependent base class thereof; or— the type of the object expression is dependent and is not the current instantiation.6If a qualified-id in which the nested-name-specifier refers to the current instantiation is not a member ofthe current instantiation or a member of an unknown specialization, the program is ill-formed even if thetemplate containing the qualified-id is not instantiated; no diagnostic required.
Similarly, if the id-expressionin a class member access expression for which the type of the object expression is the current instantiationdoes not refer to a member of the current instantiation or a member of an unknown specialization, theprogram is ill-formed even if the template containing the member access expression is not instantiated; nodiagnostic required. [ Example:template<class T> class A {typedef int type;void f() {A<T>::type i;// OK: refers to a member of the current instantiationtypename A<T>::other j; // error: neither a member of the current instantiation nor// a member of an unknown specialization}};— end example ]7If, for a given set of template arguments, a specialization of a template is instantiated that refers to a memberof the current instantiation with a qualified-id or class member access expression, the name in the qualified-id§ 14.6.2.1© ISO/IEC 2011 – All rights reserved361ISO/IEC 14882:2011(E)or class member access expression is looked up in the template instantiation context.
If the result of thislookup differs from the result of name lookup in the template definition context, name lookup is ambiguous.[ Note: the result of name lookup differs only when the member of the current instantiation was found in anon-dependent base class of the current instantiation and a member with the same name is also introducedby the substitution for a dependent base class of the current instantiation. — end note ]8A type is dependent if it is— a template parameter,— a member of an unknown specialization,— a nested class or enumeration that is a member of the current instantiation,— a cv-qualified type where the cv-unqualified type is dependent,— a compound type constructed from any dependent type,— an array type constructed from any dependent type or whose size is specified by a constant expressionthat is value-dependent,— a simple-template-id in which either the template name is a template parameter or any of the templatearguments is a dependent type or an expression that is type-dependent or value-dependent, or— denoted by decltype(expression), where expression is type-dependent (14.6.2.2).9[ Note: Because typedefs do not introduce new types, but instead simply refer to other types, a name thatrefers to a typedef that is a member of the current instantiation is dependent only if the type referred to isdependent.
— end note ]14.6.2.2Type-dependent expressions[temp.dep.expr]1Except as described below, an expression is type-dependent if any subexpression is type-dependent.2this is type-dependent if the class type of the enclosing member function is dependent (14.6.2.1).3An id-expression is type-dependent if it contains— an identifier associated by name lookup with one or more declarations declared with a dependent type,— a template-id that is dependent,— a conversion-function-id that specifies a dependent type, or— a nested-name-specifier or a qualified-id that names a member of an unknown specialization;or if it names a static data member of the current instantiation that has type “array of unknown bound ofT” for some T (14.5.1.3). Expressions of the following forms are type-dependent only if the type specified bythe type-id, simple-type-specifier or new-type-id is dependent, even if any subexpression is type-dependent:simple-type-specifier ( expression-listopt )::opt new new-placementopt new-type-id new-initializeropt::opt new new-placementopt ( type-id ) new-initializeroptdynamic_cast < type-id > ( expression )static_cast < type-id > ( expression )const_cast < type-id > ( expression )reinterpret_cast < type-id > ( expression )( type-id ) cast-expression4Expressions of the following forms are never type-dependent (because the type of the expression cannot bedependent):§ 14.6.2.2362© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)literalpostfix-expression .
pseudo-destructor-namepostfix-expression -> pseudo-destructor-namesizeof unary-expressionsizeof ( type-id )sizeof ... ( identifier )alignof ( type-id )typeid ( expression )typeid ( type-id )::opt delete cast-expression::opt delete [ ] cast-expressionthrow assignment-expressionoptnoexcept ( expression )[ Note: For the standard library macro offsetof, see 18.2. — end note ]5A class member access expression (5.2.5) is type-dependent if the expression refers to a member of the currentinstantiation and the type of the referenced member is dependent, or the class member access expressionrefers to a member of an unknown specialization. [ Note: In an expression of the form x.y or xp->y thetype 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 alwaysdependent.