Уточнённый указатель типа
Уточнённые указатели типа могут использоваться для ссылки на ранее объявленное имя класса (класс, структура или объединение) или на ранее объявленное имя перечисления, даже если это имя было скрыто объявлением нетипового объекта. Они также могут использоваться для объявления новых имён классов.
Синтаксис
| ключ-класса имя-класса | (1) | |
enum имя-перечисления | (2) | |
ключ-класса атрибут (необязательно) идентификатор ; | (3) |
| ключ-класса | - | один из class, struct, union |
| имя-класса | - | имя ранее объявленного типа класса, необязательно квалифицированное, или идентификатор, ранее не объявленный как имя типа |
| имя-перечисления | - | имя ранее объявленного типа перечисления, необязательно квалифицированное |
| атрибут | - | (с C++11) любое количество атрибутов |
Объявление неявного перечисления напоминает форму (3), но тип перечисления является полным типом после объявления неявного перечисления.
Объяснение
Форма (3) является частным случаем уточнённого указателя типа, обычно называемого предварительным объявлением классов, для описания формы (3) см. Предварительное объявление. Следующее относится только к формам (1) и (2).
Идентификатор имя-класса или имя-перечисления в уточнённом указателе типа может быть либо простым идентификатором, либо квалифицированным-идентификатором. Имя ищется с помощью поиска неуточнённого имени или поиска уточнённого имени, в зависимости от их появления. Но в любом случае имена нетиповых объектов не рассматриваются.
class T
{
public:
class U;
private:
int U;
};
int main()
{
int T;
T t; // error: the local variable T is found
class T t; // OK: finds ::T, the local variable T is ignored
T::U* u; // error: lookup of T::U finds the private data member
class T::U* u; // OK: the data member is ignored
}Если поиск имени не находит ранее объявленного имени типа, уточнённый указатель типа вводится с помощью class, struct, или union (т.е. не enum), и имя-класса является простым идентификатором, то уточнённый указатель типа является объявлением класса с именем имя-класса.
template<typename T>
struct Node
{
struct Node* Next; // OK: lookup of Node finds the injected-class-name
struct Data* Data; // OK: declares type Data at global scope
// and also declares the data member Data
friend class ::List; // error: cannot introduce a qualified name
enum Kind* kind; // error: cannot introduce an enum
};
Data* p; // OK: struct Data has been declaredЕсли имя ссылается на имя-псевдоним, псевдоним типа, параметр шаблона типа или специализацию шаблона псевдонима, программа некорректна, в противном случае уточнённый указатель типа вводит имя в объявление так же, как простой указатель типа вводит его имя типа.
template<typename T>
class Node
{
friend class T; // error: type parameter cannot appear in an elaborated type specifier
};
class A {};
enum b { f, t };
int main()
{
class A a; // OK: equivalent to 'A a;'
enum b flag; // OK: equivalent to 'b flag;'
}Ключевое слово ключ-класса или enum в уточнённом указателе типа должны соответствовать типу объявления, к которому относится имя в уточнённом указателе типа.
- ключевое слово
enumдолжно использоваться для ссылки на тип перечисления (скопированный или нескопированный) - ключевое слово
unionключ-класса должно использоваться для ссылки на объединение - ключевое слово
classилиstructключ-класса должно использоваться для ссылки на тип класса, не являющегося объединением (ключевые словаclassиstructвзаимозаменяемы здесь).
enum class E { a, b };
enum E x = E::a; // OK
enum class E y = E::b; // error: 'enum class' cannot introduce an elaborated type specifier
struct A {};
class A a; // OKКогда используется в качестве аргумента шаблона, class T является параметром шаблона типа, названным T, а не безымянным параметром нетипа, тип которого T вводится уточнённым указателем типа.
Ссылки
- Стандарт C++23 (ISO/IEC 14882:2023):
- 6.5.6 Уточнённые указатели типов [basic.lookup.elab]
- 9.2.9.4 Уточнённые указатели типов [dcl.type.elab]
- Стандарт C++20 (ISO/IEC 14882:2020):
- 6.5.4 Уточнённые указатели типов [basic.lookup.elab]
- 9.2.8.3 Уточнённые указатели типов [dcl.type.elab]
- Стандарт C++17 (ISO/IEC 14882:2017):
- 6.4.4 Уточнённые указатели типов [basic.lookup.elab]
- 10.1.7.3 Уточнённые указатели типов [dcl.type.elab]
- Стандарт C++14 (ISO/IEC 14882:2014):
- 3.4.4 Уточнённые указатели типов [basic.lookup.elab]
- 7.1.6.3 Уточнённые указатели типов [dcl.type.elab]
- Стандарт C++11 (ISO/IEC 14882:2011):
- 3.4.4 Уточнённые указатели типов [basic.lookup.elab]
- 7.1.6.3 Уточнённые указатели типов [dcl.type.elab]
- Стандарт C++98 (ISO/IEC 14882:1998):
- 3.4.4 Уточнённые указатели типов [basic.lookup.elab]
- 7.1.5.3 Уточнённые указатели типов [dcl.type.elab]
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/elaborated_type_specifier