static_assert
declaration
(since C++11)
Führt Überprüfungen zur Compile-Zeit durch.
Inhaltsverzeichnis |
Syntax
static_assert(
bool-constexpr
,
unevaluated-string
)
|
(1) | ||||||||
static_assert(
bool-constexpr
)
|
(2) | (seit C++17) | |||||||
static_assert(
bool-constexpr
,
constant-expression
)
|
(3) | (seit C++26) | |||||||
Deklariert eine statische Assertion. Wenn die Assertion fehlschlägt, ist das Programm fehlerhaft und es kann eine diagnostische Fehlermeldung generiert werden.
Erklärung
| bool-constexpr | - |
|
||||
| unevaluated-string | - | ein nicht ausgewertetes Zeichenkettenliteral , das als Fehlermeldung erscheinen wird | ||||
| constant-expression | - |
ein
konstanter Ausdruck
msg
, der alle folgenden Bedingungen erfüllt:
|
Eine static_assert -Deklaration kann im Namensraum- und Block- Scope erscheinen (als eine Blockdeklaration ) und innerhalb eines Klassenkörpers (als eine Memberdeklaration ).
Wenn bool-constexpr wohlgeformt ist und zu true ausgewertet wird, oder im Kontext einer Templatedefinition ausgewertet wird und das Template nicht instanziiert ist, hat diese Deklaration keine Wirkung. Andernfalls wird ein Kompilierzeitfehler ausgegeben, und die benutzerdefinierte Nachricht, falls vorhanden, wird in die Diagnosemeldung aufgenommen.
Der Text der vom Benutzer bereitgestellten Nachricht wird wie folgt bestimmt:
- Wenn die Nachricht den syntaktischen Anforderungen eines unevaluated-string entspricht, ist der Text der Nachricht der Text des unevaluated-string .
|
(seit C++26) |
Hinweise
Der Standard verlangt nicht, dass ein Compiler den exakten Text der Fehlermeldung ausgibt, obwohl Compiler dies im Allgemeinen so weit wie möglich tun.
|
Da die Fehlermeldung ein Zeichenkettenliteral sein muss, kann sie keine dynamischen Informationen oder sogar einen konstanten Ausdruck enthalten, der nicht selbst ein Zeichenkettenliteral ist. Insbesondere kann sie nicht den Namen des Template-Typarguments enthalten. |
(bis C++26) |
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_static_assert
|
200410L
|
(C++11) | static_assert (Syntax ( 1 ) ) |
201411L
|
(C++17) | Einargument- static_assert (Syntax ( 2 ) ) | |
202306L
|
(C++26) | Benutzerdefinierte Fehlermeldungen (Syntax ( 3 ) ) |
Schlüsselwörter
Beispiel
#include <format> #include <type_traits> static_assert(03301 == 1729); // seit C++17 ist die Nachrichten-Zeichenkette optional template<class T> void swap(T& a, T& b) noexcept { static_assert(std::is_copy_constructible_v<T>, "Swap requires copying"); static_assert(std::is_nothrow_copy_constructible_v<T> && std::is_nothrow_copy_assignable_v<T>, "Swap requires nothrow copy/assign"); auto c = b; b = a; a = c; } template<class T> struct data_structure { static_assert(std::is_default_constructible_v<T>, "Data structure requires default-constructible elements"); }; template<class> constexpr bool dependent_false = false; // Workaround vor CWG2518/P2593R1 template<class T> struct bad_type { static_assert(dependent_false<T>, "error on instantiation, workaround"); static_assert(false, "error on instantiation"); // OK wegen CWG2518/P2593R1 }; struct no_copy { no_copy(const no_copy&) = delete; no_copy() = default; }; struct no_default { no_default() = delete; }; #if __cpp_static_assert >= 202306L // Noch kein echtes C++ (std::format müsste constexpr sein, um zu funktionieren): static_assert(sizeof(int) == 4, std::format("Expected 4, got {}", sizeof(int))); #endif int main() { int a, b; swap(a, b); no_copy nc_a, nc_b; swap(nc_a, nc_b); // 1 [[maybe_unused]] data_structure<int> ds_ok; [[maybe_unused]] data_structure<no_default> ds_error; // 2 }
Mögliche Ausgabe:
1: Fehler: Static Assertion fehlgeschlagen: Swap requires copying 2: Fehler: Static Assertion fehlgeschlagen: Data structure requires default-constructible elements 3: Fehler: Static Assertion fehlgeschlagen: Expected 4, got 2
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 2039 | C++11 | nur der Ausdruck vor der Konvertierung musste konstant sein |
die Konvertierung muss ebenfalls
in einem konstanten Ausdruck gültig sein |
|
CWG 2518
( P2593R1 ) |
C++11 | nicht instanziierte static_assert ( false , "" ) ; war fehlerhaft | als korrekt definiert |
Referenzen
- C++23-Standard (ISO/IEC 14882:2024):
-
- 9.1 Präambel [dcl.pre] (S.: 10)
- C++20-Standard (ISO/IEC 14882:2020):
-
- 9.1 Präambel [dcl.pre] (S.: 6)
- C++17-Standard (ISO/IEC 14882:2017):
-
- 10 Deklarationen [dcl.dcl] (S.: 6)
- C++14-Standard (ISO/IEC 14882:2014):
-
- 7 Deklarationen [dcl.dcl] (S.: 4)
- C++11-Standard (ISO/IEC 14882:2011):
-
- 7 Deklarationen [dcl.dcl] (S: 4)
Siehe auch
|
zeigt die angegebene Fehlermeldung an und macht das Programm fehlerhaft
(Präprozessor-Direktive) |
|
|
bricht das Programm ab, wenn die benutzerdefinierte Bedingung nicht
true
ist. Kann für Release-Builds deaktiviert werden.
(Funktionsmakro) |
|
contract_assert
statement
(C++26)
|
überprüft eine interne Bedingung während der Ausführung |
|
(C++11)
|
entfernt bedingt
eine Funktionsüberladung oder Templatespezialisierung
aus der Überladungsauflösung
(Klassentemplate) |
| Type traits (C++11) | definiert kompilierzeit-template-basierte Schnittstellen zum Abfragen von Typeigenschaften |
|
C-Dokumentation
für
Statische Assertion
|
|