Namespaces
Variants

Elaborated type specifier

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Уточненные спецификаторы типа могут использоваться для обращения к ранее объявленному имени класса (class, struct или union) или к ранее объявленному имени перечисления, даже если имя было скрыто объявлением не-типа . Они также могут использоваться для объявления новых имен классов.

Содержание

Синтаксис

class-key class-name (1)
enum enum-name (2)
class-key attr  (необязательно) identifier ; (3)
class-key - один из class , struct , union
class-name - имя ранее объявленного типа класса, опционально квалифицированное , или идентификатор, ранее не объявленный как имя типа
enum-name - имя ранее объявленного типа перечисления, опционально квалифицированное
attr - (начиная с C++11) любое количество атрибутов
1) Уточненный спецификатор типа для типа класса.
2) Уточненный спецификатор типа для перечислимого типа.
3) Объявление, состоящее исключительно из уточненного спецификатора типа, всегда объявляет тип класса с именем identifier в области видимости , содержащей это объявление.

Объявление непрозрачного перечисления напоминает форму (3) , но тип перечисления становится полным типом после объявления непрозрачного перечисления.

Объяснение

Форма (3) является частным случаем elaborated type specifier, обычно называемым forward declaration классов. Для описания формы (3) см. Forward declaration . Следующее относится только к форме (1) и (2) .

class-name или enum-name в уточненном спецификаторе типа может быть либо простым идентификатором, либо qualified-id . Поиск имени выполняется с использованием unqualified name lookup или qualified name lookup , в зависимости от их формы. Однако в обоих случаях имена не-типов не рассматриваются.

class T
{
public:
    class U;
private:
    int U;
};
int main()
{
    int T; // ошибка: найдена локальная переменная T
    class T t; // OK: находит ::T, локальная переменная T игнорируется
    T::U* u; // ошибка: поиск T::U находит приватный член данных
    class T::U* u; // OK: член данных игнорируется
}

Если поиск имени не находит ранее объявленное имя типа, а уточненный-спецификатор-типа вводится с помощью class , struct , или union (т.е. не с помощью enum ), и class-name является неквалифицированным идентификатором, тогда уточненный-спецификатор-типа является объявлением класса с именем class-name, и целевой областью видимости является ближайшая охватывающая пространство имен или блочная область видимости.

template<typename T>
struct Node
{
    struct Node* Next; // OK: поиск Node находит injected-class-name
    struct Data* Data; // OK: объявляет тип Data в глобальной области видимости
                       // и также объявляет член данных Data
    friend class ::List; // ошибка: нельзя вводить квалифицированное имя
    enum Kind* kind; // ошибка: нельзя вводить перечисление
};
Data* p; // OK: структура Data была объявлена

Если имя ссылается на typedef-имя , псевдоним типа , параметр шаблона типа или специализацию шаблона псевдонима , программа является некорректной, в противном случае уточненный спецификатор типа вводит имя в объявление таким же образом, как простой спецификатор типа вводит свое имя-типа.

template<typename T>
class Node
{
    friend class T; // ошибка: параметр типа не может использоваться в уточненном спецификаторе типа;
                    // примечание: аналогичное объявление `friend T;` допустимо.
};
class A {};
enum b { f, t };
int main()
{
    class A a; // OK: эквивалентно 'A a;'
    enum b flag; // OK: эквивалентно 'b flag;'
}

class-key или ключевое слово enum в уточненном спецификаторе типа должны соответствовать по типу объявлению, на которое ссылается имя в уточненном спецификаторе типа.

  • ключевое слово enum должно использоваться для обращения к типу перечисления (будь то область видимости или без области видимости)
  • ключевое слово union class-key должно использоваться для обращения к объединению
  • либо ключевое слово class или struct class-key должно использоваться для обращения к типу класса, не являющемуся объединением (ключевые слова class и struct здесь взаимозаменяемы).
enum class E { a, b };
enum E x = E::a; // OK
enum class E y = E::b; // ошибка: 'enum class' не может использоваться в уточненном спецификаторе типа
struct A {};
class A a; // OK

При использовании в качестве аргумента шаблона , class T является параметром шаблона типа с именем T , а не безымянным параметром-константой, тип T которого вводится спецификатором elaborated type.

Ключевые слова

class , struct , union , enum

Ссылки

  • Стандарт C++23 (ISO/IEC 14882:2024):
  • 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]