Namespaces
Variants

Declarations

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

Deklarationen sind die Art und Weise, wie Namen in das C++-Programm eingeführt (oder wieder eingeführt) werden. Nicht alle Deklarationen deklarieren tatsächlich etwas, und jede Art von Entität wird unterschiedlich deklariert. Definitionen sind Deklarationen, die ausreichen, um die durch den Namen identifizierte Entität zu verwenden.

Eine Deklaration ist eines der folgenden Elemente:

  • Attributdeklaration ( attr ; )
(seit C++11)
  • Leere Deklaration ( ; )
  • Eine Funktionsdeklaration ohne decl-specifier-seq :
attr  (optional) declarator ;
attr - (since C++11) Folge beliebig vieler attributes
declarator - ein Funktionsdeklarator
Diese Deklaration muss einen Konstruktor, Destruktor oder eine benutzerdefinierte Konvertierungsfunktion deklarieren. Sie kann nur als Teil einer Template-Deklaration , expliziten Spezialisierung oder expliziten Instanziierung verwendet werden.
  • block-declaration (eine Deklaration, die innerhalb eines Blocks erscheinen kann), die wiederum eine der folgenden sein kann:
(seit C++11)
(seit C++20)
(seit C++11)
  • einfache Deklaration

Inhaltsverzeichnis

Einfache Deklaration

Eine einfache Deklaration ist eine Anweisung, die einen oder mehrere Bezeichner, typischerweise Variablen, einführt, erstellt und optional initialisiert.

decl-specifier-seq init-declarator-list  (optional) ; (1)
attr decl-specifier-seq init-declarator-list ; (2) (seit C++11)
decl-specifier-seq - Folge von Spezifizierern
init-declarator-list - kommagetrennte Liste von init-declarator s (siehe unten)
attr - Folge beliebig vieler Attribute


init-declarator-list kann nur beim Deklarieren einer benannten Klasse oder einer benannten Enumeration weggelassen werden.

Eine strukturierte Bindungsdeklaration ist ebenfalls eine einfache Deklaration.

(seit C++17)


Die Syntax von init-declarator ist wie folgt definiert:

declarator initializer (1)
declarator requires-clause  (optional) contract-specs  (optional) (2)
1) Ein Deklarator mit einem Initialisierer.
2) Ein Deklarator ohne Initialisierer.
declarator - ein Deklarator
initializer - ein Initialisierer
requires-clause - (since C++20) eine requires -Klausel
contract-specs - (since C++26) eine Liste von Funktionsvertragsspezifizierern


requires-clause darf nur erscheinen, wenn der declarator eine templated function deklariert.

(since C++20)

contract-specs dürfen nur erscheinen, wenn der declarator eine Funktion oder Funktionsvorlage deklariert.

(since C++26)

Spezifizierer

Deklarationsspezifizierer ( decl-specifier-seq ) ist eine Sequenz der folgenden, durch Leerzeichen getrennten Spezifizierer in beliebiger Reihenfolge:

  • der inline Spezifizierer ist ebenfalls bei Variablendeklarationen erlaubt.
(seit C++17)
  • der friend Spezifizierer, erlaubt in Klassen- und Funktionsdeklarationen.
  • der constexpr Spezifizierer, nur erlaubt in Variablendefinitionen, Funktions- und Funktions-Template-Deklarationen sowie der Deklaration statischer Datenelemente von Literaltypen.
(seit C++11)
  • der consteval Spezifizierer, nur erlaubt in Funktions- und Funktions-Template-Deklarationen.
  • der constinit Spezifizierer, nur erlaubt in der Deklaration einer Variable mit statischer oder Thread-Speicherdauer. Höchstens einer der constexpr , consteval , und constinit Spezifizierer darf in einer decl-specifier-seq vorkommen.
(seit C++20)
  • Speicherklassenspezifizierer ( register , (bis C++17) static , thread_local , (seit C++11) extern , mutable ). Nur ein Speicherklassenspezifizierer ist erlaubt , außer dass thread_local zusammen mit extern oder static auftreten darf (seit C++11) .
  • Typspezifizierer ( type-specifier-seq ), eine Sequenz von Spezifizierern, die einen Typ benennt. Der Typ jeder durch die Deklaration eingeführten Entität ist dieser Typ, optional modifiziert durch den Deklarator (siehe unten). Diese Sequenz von Spezifizierern wird auch von type-id verwendet. Nur die folgenden Spezifizierer sind Teil von type-specifier-seq , in beliebiger Reihenfolge:
(seit C++11)
(seit C++26)
(seit C++17)
nur ein Typ-Spezifizierer ist in einer decl-specifier-seq erlaubt, mit folgenden Ausnahmen:
  • const kann mit jedem Typ-Spezifizierer kombiniert werden, außer mit sich selbst.
  • volatile kann mit jedem Typ-Spezifizierer kombiniert werden, außer mit sich selbst.
  • signed oder unsigned kann kombiniert werden mit char , long , short , oder int .
  • short oder long kann kombiniert werden mit int .
  • long kann kombiniert werden mit double .
  • long kann mit long kombiniert werden.
(seit C++11)

Attribute können in decl-specifier-seq erscheinen, in welchem Fall sie auf den durch die vorhergehenden Spezifizierer bestimmten Typ angewendet werden.

Wiederholungen jeglicher Spezifizierer in einer decl-specifier-seq , wie const static const oder virtual inline virtual sind Fehler , außer dass long zweimal auftreten darf (seit C++11) .

Deklaratoren

Jeder init-declarator in einer init-declarator-list S D1, D2, D3 ; wird so verarbeitet, als wäre es eine eigenständige Deklaration mit denselben Spezifizierern: S D1 ; S D2 ; S D3 ; .

Jeder Deklarator führt genau ein Objekt, eine Referenz, eine Funktion oder (für typedef-Deklarationen) einen Typalias ein, dessen Typ durch die decl-specifier-seq bereitgestellt und optional durch Operatoren wie & (Referenz auf) oder [ ] (Array von) oder ( ) (Funktion zurückgebend) im Deklarator modifiziert wird. Diese Operatoren können rekursiv angewendet werden, wie unten gezeigt.

Ein Deklarator ist einer der folgenden:

unqualified-id attr  (optional) (1)
qualified-id attr  (optional) (2)
... identifier attr  (optional) (3) (seit C++11)
* attr  (optional) cv  (optional) declarator (4)
nested-name-specifier * attr  (optional) cv  (optional) declarator (5)
& attr  (optional) declarator (6)
&& attr  (optional) declarator (7) (seit C++11)
noptr-declarator [ constant-expression  (optional) ] attr  (optional) (8)
noptr-declarator ( parameter-list ) cv  (optional) ref   (optional) except  (optional) attr  (optional) (9)
( declarator ) (10)
1) Der Name der deklariert wird.
2) Ein Deklarator, der einen qualified identifier ( qualified-id ) verwendet, definiert oder deklariert erneut ein zuvor deklariertes namespace member oder class member .
4) Pointer-Deklarator : die Deklaration S * D ; deklariert D als einen Zeiger auf den durch Deklarator-Spezifizierer-Sequenz S bestimmten Typ.
5) Deklaration eines Zeigers auf Mitglied : die Deklaration S C :: * D ; deklariert D als einen Zeiger auf ein Mitglied von C vom Typ, bestimmt durch Deklarationsspezifizierer-Sequenz S . Verschachtelter-Namen-Spezifizierer ist eine Sequenz von Namen und Bereichsauflösungsoperatoren ::
6) Lvalue-Referenzdeklarator : die Deklaration S & D ; deklariert D als eine Lvalue-Referenz auf den durch decl-specifier-seq S bestimmten Typ.
7) Rvalue-Referenzdeklarator : die Deklaration S && D ; deklariert D als eine Rvalue-Referenz auf den durch Deklarator-Spezifizierer-Sequenz S bestimmten Typ.
8) Array-Deklarator . noptr-declarator jeder gültige Deklarator, aber wenn er mit *, & oder && beginnt, muss er in Klammern eingeschlossen werden.
9) Funktionsdeklarator . noptr-declarator jeder gültige Deklarator, aber wenn er mit *, & oder && beginnt, muss er in Klammern eingeschlossen sein. Er kann mit dem optionalen nachgestellten Rückgabetyp enden. (seit C++11)
10) Geklammerter Deklarator.

In allen Fällen ist attr eine optionale Folge von Attributen . Wenn es unmittelbar nach dem Bezeichner erscheint, gilt es für das deklarierte Objekt.

(since C++11)

cv ist eine Sequenz von const- und volatile Qualifizierern, wobei jeder Qualifizierer höchstens einmal in der Sequenz vorkommen darf.

Hinweise

Wenn eine block-declaration innerhalb eines Blocks erscheint und ein durch eine Deklaration eingeführter Bezeichner zuvor in einem äußeren Block deklariert wurde, wird die äußere Deklaration für den Rest des Blocks verborgen.

Wenn eine Deklaration eine Variable mit automatischer Speicherdauer einführt, wird sie initialisiert, wenn ihre Deklarationsanweisung ausgeführt wird. Alle automatischen Variablen, die in einem Block deklariert werden, werden beim Verlassen des Blocks zerstört (unabhängig davon, wie der Block verlassen wird: via exception , goto , oder durch Erreichen seines Endes), in umgekehrter Reihenfolge ihrer Initialisierung.

Beispiel

Hinweis: Dieses Beispiel demonstriert, wie einige komplexe Deklarationen gemäß der Sprachgrammatik geparst werden. Andere bekannte Merkhilfen sind: die Spiralregel , das Lesen von innen nach außen , und Deklaration spiegelt Verwendung . Es gibt auch einen automatisierten Parser unter https://cdecl.org .

#include <type_traits>
struct S
{
    int member;
    // decl-specifier-seq is "int"
    // declarator is "member"
{ obj, *pObj(&obj);
// decl-specifier-seq is "struct S { int member; }"
// declarator "obj" declares an object of type S
// declarator "*pObj" declares a pointer to S,
//     and initializer "(&obj)" initializes it
int i = 1, *p = nullptr, f(), (*pf)(double);
// decl-specifier-seq is "int"
// declarator "i" declares a variable of type int,
//     and initializer "= 1" initializes it
// declarator "*p" declares a variable of type int*,
//     and initializer "= nullptr" initializes it
// declarator "f()" declares (but doesn't define)
//     a function taking no arguments and returning int
// declarator "(*pf)(double)" declares a pointer to function
//     taking double and returning int
int (*(*var1)(double))[3] = nullptr;
// decl-specifier-seq is "int"
// declarator is "(*(*var1)(double))[3]"
// initializer is "= nullptr"
// 1. declarator "(*(*var1)(double))[3]" is an array declarator:
//    Type declared is: "(*(*var1)(double))" array of 3 elements
// 2. declarator "(*(*var1)(double))" is a pointer declarator:
//    Type declared is: "(*var1)(double)" pointer to array of 3 elements
// 3. declarator "(*var1)(double)" is a function declarator:
//    Type declared is: "(*var1)" function taking "(double)",
//    returning pointer to array of 3 elements.
// 4. declarator "(*var1)" is a pointer declarator:
//    Type declared is: "var1" pointer to function taking "(double)",
//    returning pointer to array of 3 elements.
// 5. declarator "var1" is an identifier.
// This declaration declares the object var1 of type "pointer to function
// taking double and returning pointer to array of 3 elements of type int"
// The initializer "= nullptr" provides the initial value of this pointer.
// C++11 alternative syntax:
auto (*var2)(double) -> int (*)[3] = nullptr;
// decl-specifier-seq is "auto"
// declarator is "(*var2)(double) -> int (*)[3]"
// initializer is "= nullptr"
// 1. declarator "(*var2)(double) -> int (*)[3]" is a function declarator:
//    Type declared is: "(*var2)" function taking "(double)", returning "int (*)[3]"
// ...
int main()
{
    static_assert(std::is_same_v<decltype(var1), decltype(var2)>);
}

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
CWG 482 C++98 die Deklaratoren von Neudeklarationen konnten nicht qualifiziert werden qualifizierte Deklaratoren erlaubt
CWG 569 C++98 ein einzelnes eigenständiges Semikolon war keine gültige Deklaration es ist eine leere Deklaration,
die keine Wirkung hat
CWG 1830 C++98 Wiederholung eines Funktionsspezifizierers in einer decl-specifier-seq war erlaubt Wiederholung ist verboten

Siehe auch

C-Dokumentation für Deklarationen