Namensräume
Varianten
Aktionen

Elaborierter Typ-Spezifizierer

Von cppreference.com
< cpp‎ | Sprache
 
 
C++ Sprache
Allgemeine Themen
Kontrollfluss
Bedingte Ausführungsaussagen
if
Iterationsanweisungen (Schleifen)
for
Bereichs-for (C++11)
Sprunganweisungen
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauer-Spezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesch - Ganzzahl - Gleitkommazahl
Zeichen - String - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Spezielle Member-Funktionen
Templates
Sonstiges
 
 

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

Inhalt

[bearbeiten] Syntax

class-key class-name (1)
enum enum-name (2)
class-key attr (optional) identifier ; (3)
class-key - einer von class, struct, union
Klassenname - 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 Enumerationstyps, optional qualifiziert
attr - (seit C++11) eine beliebige Anzahl von Attributen
1) Ausführlicher Typ-Spezifizierer für einen Klassentyp.
2) Ausführlicher Typ-Spezifizierer für einen Enumerationstyp.
3) Eine Deklaration, die ausschließlich aus einem ausführlichen Typ-Spezifizierer besteht, deklariert immer einen Klassentyp mit dem Namen identifier im Gültigkeitsbereich, der die Deklaration enthält.

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

[bearbeiten] Erklärung

Form (3) ist ein Sonderfall des ausführlichen Typ-Spezifizierers, der üblicherweise als Vorwärtsdeklaration von Klassen bezeichnet wird. Für die Beschreibung von Form (3) siehe Vorwärtsdeklaration. Das Folgende gilt nur für Form (1) und (2).

Der class-name oder enum-name im ausführlichen Typ-Spezifizierer kann entweder ein einfacher Bezeichner oder eine qualifizierte ID sein. Die Namenssuche erfolgt mithilfe von unqualifizierter Namenssuche oder qualifizierter Namenssuche, je nach Erscheinungsbild. In jedem Fall werden jedoch keine Nicht-Typ-Namen berücksichtigt.

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
}

Wenn die Namenssuche keinen zuvor deklarierten Typnamen findet, der ausführliche Typ-Spezifizierer mit class, struct oder union (d. h. nicht mit enum) eingeleitet wird und class-name ein unqualifizierter Bezeichner ist, dann ist der ausführliche Typ-Spezifizierer eine Klassendeklaration des class-name, und der Ziel-Gültigkeitsbereich ist der nächste umschließende Namespace oder Block-Gültigkeitsbereich.

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

Wenn der Name auf einen typedef-Namen, einen Typ-Alias, einen Typ-Template-Parameter oder eine Alias-Template-Spezialisierung verweist, ist das Programm ill-formed, andernfalls führt der ausführliche Typ-Spezifizierer den Namen in die Deklaration ein, genauso wie ein einfacher Typ-Spezifizierer seinen Typ-Namen einführt.

template<typename T>
class Node
{
    friend class T; // error: type parameter cannot appear in an elaborated type specifier;
                    // note that similar declaration `friend T;` is OK.
};
 
class A {};
enum b { f, t };
 
int main()
{
    class A a; // OK: equivalent to 'A a;'
    enum b flag; // OK: equivalent to 'b flag;'
}

Der class-key oder das Schlüsselwort enum im ausführlichen Typ-Spezifizierer muss in seiner Art mit der Deklaration übereinstimmen, auf die sich der Name im ausführlichen Typ-Spezifizierer bezieht.

  • Das Schlüsselwort enum muss verwendet werden, um auf einen Enumerationstyp (egal ob geschachtelt oder ungeschachtelt) zu verweisen.
  • Der class-key union muss verwendet werden, um auf eine union zu verweisen.
  • Entweder der class-key class oder struct muss verwendet werden, um auf einen Nicht-Union-Klassentyp zu verweisen (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; // error: 'enum class' cannot introduce an elaborated type specifier
 
struct A {};
class A a; // OK

Wenn es als Template-Argument verwendet wird, ist class T ein Typ-Template-Parameter namens T und kein unbenannter Nicht-Typ-Parameter, dessen Typ T durch einen ausführlichen Typ-Spezifizierer eingeführt wird.

[bearbeiten] Schlüsselwörter

class, struct, union, enum

[bearbeiten] 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 Elaborated type specifiers [basic.lookup.elab]
  • 10.1.7.3 Elaborated type specifiers [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]