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

Ausgeführte Typspezifizierer können verwendet werden, um auf einen zuvor deklarierten Klassennamen (class, struct oder union) oder einen zuvor deklarierten Enum-Namen zu verweisen, selbst wenn der Name durch eine Nicht-Typ-Deklaration verborgen wurde . Sie können auch verwendet werden, um neue Klassennamen zu deklarieren.

Inhaltsverzeichnis

Syntax

class-key class-name (1)
enum enum-name (2)
class-key attr  (optional) identifier ; (3)
class-key - einer von class , struct , union
class-name - der Name eines zuvor deklarierten Klassentyps, optional qualifiziert , oder ein Bezeichner, der nicht zuvor als Typname deklariert wurde
enum-name - der Name eines zuvor deklarierten Aufzählungstyps, optional qualifiziert
attr - (seit C++11) beliebig viele attributes
1) Ausgearbeiteter Typspezifizierer für einen Klassentyp.
2) Ausgearbeiteter Typspezifizierer für einen Aufzählungstyp.
3) Eine Deklaration, die ausschließlich aus einem spezifizierten Typbezeichner besteht, deklariert stets einen Klassentyp mit dem Namen identifier im Gültigkeitsbereich , der die Deklaration enthält.

Opaque enum declaration ähnelt der Form (3) , aber der Enum-Typ ist nach einer Opaque enum declaration ein vollständiger Typ.

Erklärung

Form (3) ist ein Sonderfall eines elaborated type specifier, üblicherweise bezeichnet als forward declaration von Klassen. Für die Beschreibung von Form (3) siehe Forward declaration . Die folgenden Ausführungen gelten nur für Form (1) und (2) .

Der class-name oder enum-name im elaborated type specifier kann entweder ein einfacher Bezeichner oder eine qualified-id sein. Der Name wird mittels unqualified name lookup oder qualified name lookup gesucht, abhängig von deren Erscheinungsform. In beiden Fällen werden jedoch keine Nicht-Typ-Namen berücksichtigt.

class T
{
public:
    class U;
private:
    int U;
};
int main()
{
    int T;
    T t; // Fehler: Die lokale Variable T wird gefunden
    class T t; // OK: findet ::T, die lokale Variable T wird ignoriert
    T::U* u; // Fehler: Suche nach T::U findet das private Datenelement
    class T::U* u; // OK: Das Datenelement wird ignoriert
}

Wenn die Namenssuche keinen zuvor deklarierten Typnamen findet, der elaborated-type-specifier durch class , struct , oder union eingeleitet wird (d.h. nicht durch enum ), und class-name ein unqualifizierter Bezeichner ist, dann ist der elaborated-type-specifier eine Klassendeklaration des class-name, und der Zielbereich ist der nächstgelegene umschließende Namensraum oder Blockbereich.

template<typename T>
struct Node
{
    struct Node* Next; // OK: Suche nach Node findet den injizierten Klassennamen
    struct Data* Data; // OK: deklariert Typ Data im globalen Gültigkeitsbereich
                       // und deklariert auch das Datenelement Data
    friend class ::List; // Fehler: qualifizierter Name kann nicht eingeführt werden
    enum Kind* kind; // Fehler: Enum kann nicht eingeführt werden
};
Data* p; // OK: struct Data wurde deklariert

Wenn der Name auf einen typedef-Namen , einen Typ-Alias , einen Template-Typparameter oder eine Alias-Template-Spezialisierung verweist, ist das Programm fehlerhaft; andernfalls führt der elaborierte Typspezifizierer den Namen in die Deklaration auf die gleiche Weise ein, wie ein einfacher Typspezifizierer seinen Typnamen einführt.

template<typename T>
class Node
{
    friend class T; // Fehler: Typparameter kann nicht in einem spezifizierten Typbezeichner vorkommen;
                    // Hinweis: Ähnliche Deklaration `friend T;` ist korrekt.
};
class A {};
enum b { f, t };
int main()
{
    class A a; // OK: Entspricht 'A a;'
    enum b flag; // OK: Entspricht 'b flag;'
}

Das class-key oder enum Schlüsselwort, das im elaborated-type-specifier vorhanden ist, muss in der Art mit der Deklaration übereinstimmen, auf die der Name im elaborated-type-specifier verweist.

  • das enum Schlüsselwort muss verwendet werden, um sich auf einen Aufzählungstyp (ob scoped oder unscoped) zu beziehen
  • das union class-key muss verwendet werden, um sich auf eine Union zu beziehen
  • entweder das class oder struct class-key muss verwendet werden, um sich auf einen Nicht-Union-Klassentyp zu beziehen (die Schlüsselwörter class und struct sind hier austauschbar).
enum class E { a, b };
enum E x = E::a; // OK
enum class E y = E::b; // Fehler: 'enum class' kann keinen elaborated type specifier einführen
struct A {};
class A a; // OK

Wenn es als Template-Argument verwendet wird, class T ist ein Typ-Template-Parameter namens T , kein unbenannter konstanter Parameter, dessen Typ T durch einen erweiterten Typspezifizierer eingeführt wird.

Schlüsselwörter

class , struct , union , enum

Referenzen

  • C++23-Standard (ISO/IEC 14882:2024):
  • 6.5.6 Elaborated type specifiers [basic.lookup.elab]
  • 9.2.9.4 Elaborated type specifiers [dcl.type.elab]
  • C++20-Standard (ISO/IEC 14882:2020):
  • 6.5.4 Elaborated type specifiers [basic.lookup.elab]
  • 9.2.8.3 Elaborated type specifiers [dcl.type.elab]
  • C++17-Standard (ISO/IEC 14882:2017):
  • 6.4.4 Elaborierte Typspezifizierer [basic.lookup.elab]
  • 10.1.7.3 Elaborierte Typspezifizierer [dcl.type.elab]
  • C++14-Standard (ISO/IEC 14882:2014):
  • 3.4.4 Elaborated type specifiers [basic.lookup.elab]
  • 7.1.6.3 Elaborated type specifiers [dcl.type.elab]
  • C++11-Standard (ISO/IEC 14882:2011):
  • 3.4.4 Elaborated type specifiers [basic.lookup.elab]
  • 7.1.6.3 Elaborated type specifiers [dcl.type.elab]
  • C++98 Standard (ISO/IEC 14882:1998):
  • 3.4.4 Elaborated type specifiers [basic.lookup.elab]
  • 7.1.5.3 Elaborated type specifiers [dcl.type.elab]