Имя относится к тому, current instantiation если это
в определении шаблона класса, вложенного класса шаблона класса, члена шаблона класса или члена вложенного класса шаблонаinjected-class-name класса, шаблона класса или вложенного класса,
в определении шаблона первичного класса или члена шаблона первичного класса, имя шаблона класса, за которым следует список аргументов шаблона первичного шаблона (как описано ниже), заключенный в <> (или эквивалентную специализацию псевдонима шаблона),
в определении вложенного класса шаблона класса имя вложенного класса, на который ссылается как на член текущего экземпляра, или
в определении частичной специализации или члена частичной специализации - имя шаблона класса, за которым следует список аргументов шаблона частичной специализации, заключенной в <> (или эквивалентная специализация псевдонима шаблона). Если параметрnth шаблона является пакетом параметров,nаргумент шаблона th является pack expansion шаблоном, шаблон которого является именем пакета параметров.
Список аргументов шаблона первичного шаблона - это список аргументов шаблона, в котором nаргумент th шаблона имеет значение параметра nth шаблона шаблона класса. Еслиnth параметром шаблона является a template parameter pack,nаргумент th шаблона - это a pack expansion , шаблон которого является именем пакета параметров шаблона.
Аргумент шаблона, который эквивалентен параметру шаблона (т. Е. Имеет то же постоянное значение или тот же тип, что и параметр шаблона), может использоваться вместо этого параметра шаблона в ссылке на текущий экземпляр. В случае аргумента шаблона, не являющегося типом, аргументу должно быть задано значение параметра шаблона, а не выражение, в котором параметр шаблона появляется как часть выражения. [ Example:
template <class T> class A { A* p1; // A is the current instantiation A<T>* p2; // A<T> is the current instantiation A<T*> p3; // A<T*> is not the current instantiation ::A<T>* p4; // ::A<T> is the current instantiation class B { B* p1; // B is the current instantiation A<T>::B* p2; // A<T>::B is the current instantiation typename A<T*>::B* p3; // A<T*>::B is not the current instantiation }; }; template <class T> class A<T*> { A<T*>* p1; // A<T*> is the current instantiation A<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 instantiation B<T2, T1, I>* b2; // not the current instantiation typedef 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 instantiation B<my_T1, T2, my_I2>* b4; // not the current instantiation B<my_T1, T2, my_I3>* b5; // refers to the current instantiation };
— end example ]
Adependent base class - это базовый класс, который является зависимым типом и не является текущим экземпляром. [ Note: Базовый класс может быть текущим экземпляром в случае, если вложенный класс называет включающий класс базовым. [ Example:
template<class T> struct A {
typedef int M;
struct B {
typedef void M;
struct C;
};
};
template<class T> struct A<T>::B::C : A<T> {
M m; // OK, A<T>::M
};
— end example ] ] — end note
Имя - это member of the current instantiation если это
Неквалифицированное имя, которое при поиске относится по крайней мере к одному члену класса, который является текущим экземпляром или его независимым базовым классом. [ Note: Это может произойти только при поиске имени в области, содержащейся в определении шаблона класса. ] — end note
A, qualified-id в котором nested-name-specifier относится к текущему экземпляру и который при поиске относится по крайней мере к одному члену класса, который является текущим экземпляром, или его независимым базовым классом. [ Note: Если такой член не найден, а у текущего экземпляра есть какие-либо зависимые базовые классы, то qualified-idэто член неизвестной специализации; см. ниже. ] — end note
id-expressionОбозначая член вclass member access выражении для которого тип выражения объекта является текущим конкретизации, и id-expression, когдаlooked up, относится к по меньшей мере , одного члена класса , который является текущим конкретизации или не зависящих от их базового класса. [ Note: Если такой член не найден, а у текущего экземпляра есть какие-либо зависимые базовые классы, то id-expressionэто член неизвестной специализации; см. ниже. ] — end note
[ Example:
template <class T> class A { static const int i = 5; int n1[i]; // i refers to a member of the current instantiation int n2[A::i]; // A::i refers to a member of the current instantiation int n3[A<T>::i]; // A<T>::i refers to a member of the current instantiation int f(); }; template <class T> int A<T>::f() { return i; // i refers to a member of the current instantiation }
— end example ]
Имя - это,dependent member of the current instantiation если он является членом текущего экземпляра, который при поиске ссылается по крайней мере на один член класса, который является текущим экземпляром.
Имя - это member of an unknown specialization если это
Объект, qualified-id в котором nested-name-specifier именуется зависимый тип, не являющийся текущим экземпляром.
A, qualified-idв котором nested-name-specifier относится к текущему экземпляру, текущий экземпляр имеет по крайней мере один зависимый базовый класс, а поиск имени qualified-idне находит ни одного члена класса, который является текущим экземпляром или его независимым базовым классом.
id-expressionОбозначая член в class member access выражении , в котором либо
тип объектного выражения - это текущая реализация, текущая реализация имеет по крайней мере один зависимый базовый класс, а поиск имени id-expressionне находит члена класса, который является текущим экземпляром, или его независимого базового класса; или
тип объектного выражения является зависимым и не является текущим экземпляром.
Если a, qualified-idв котором nested-name-specifier относится к текущему экземпляру, не является членом текущего экземпляра или элементом неизвестной специализации, программа имеет неправильный формат, даже если шаблон, содержащий элемент, не создается qualified-id; диагностика не требуется. Точно так же, если id-expressionвыражение доступа к члену класса, для которого тип выражения объекта является текущим экземпляром, не относится к члену текущего экземпляра или члену неизвестной специализации, программа имеет неправильный формат, даже если шаблон содержащее выражение доступа к члену не создается; диагностика не требуется. [ Example:
template<class T> class A { typedef int type; void f() { A<T>::type i; // OK: refers to a member of the current instantiation typename A<T>::other j; // error: neither a member of the current instantiation nor // a member of an unknown specialization } };
— end example ]
Если для заданного набора аргументов шаблона создается экземпляр специализации шаблона, который ссылается на член текущего экземпляра с qualified-idвыражением доступа к члену класса or, имя в qualified-idвыражении доступа к члену класса or ищется в экземпляре шаблона. контекст. Если результат этого поиска отличается от результата поиска имени в контексте определения шаблона, поиск имени неоднозначен. [ Example:
struct A { int m; }; struct B { int m; }; template<typename T> struct C : A, T { int f() { return this->m; } // finds A::m in the template definition context int g() { return m; } // finds A::m in the template definition context }; template int C<B>::f(); // error: finds both A::m and B::m template int C<B>::g(); // OK: transformation to class member access syntax // does not occur in the template definition context; see [class.mfct.non-static]
— end example ]
Тип является зависимым, если он
параметр шаблона,
сотрудник неизвестной специализации,
вложенный класс или перечисление, которое является зависимым членом текущего экземпляра,
тип cv-qualified, где cv-unqualified тип является зависимым,
составной тип, созданный из любого зависимого типа,
тип массива, тип элемента которого является зависимым или чья граница (если есть) зависит от значения,
тип функции, спецификация исключения которой зависит от значения,
a, simple-template-id в котором либо имя шаблона является параметром шаблона, либо любой из аргументов шаблона является зависимым типом или выражением, которое зависит от типа или значения, или является расширением пакета [ Note: Сюда входитinjected-class-name шаблон класса, используемый без расширения template-argument-list. ] , или — end note
обозначается , где есть . decltype(expression)expressiontype-dependent