consteval
specifier
(since C++20)
-
-
consteval- gibt an, dass eine Funktion eine Immediate-Funktion ist, das heißt, jeder Aufruf der Funktion muss ein Kompilierzeit-Konstante erzeugen
-
Inhaltsverzeichnis |
Erklärung
Der
consteval
-Spezifizierer deklariert eine Funktion oder Funktionsvorlage als
unmittelbare Funktion
, das heißt, jeder
potenziell ausgewertete
Aufruf der Funktion muss (direkt oder indirekt) einen Compile-Zeit-
konstanten Ausdruck
erzeugen.
Eine Immediate-Funktion ist eine
constexpr-Funktion
, die je nach Fall ihren Anforderungen unterliegt. Wie bei
constexpr
impliziert ein
consteval
-Spezifizierer ebenfalls
inline
. Allerdings darf es nicht auf Destruktoren, Allokierungsfunktionen oder Deallokierungsfunktionen angewendet werden.
Eine Funktions- oder Funktions-Template-Deklaration, die
consteval
spezifiziert, darf nicht ebenfalls
constexpr
spezifizieren, und alle Neudeklarationen dieser Funktion oder dieses Funktions-Templates müssen ebenfalls
consteval
spezifizieren.
Ein potenziell ausgewerteter Aufruf einer Immediate-Funktion, deren innerster Nicht-Block-Gültigkeitsbereich kein Funktionsparameter-Gültigkeitsbereich einer Immediate-Funktion ist oder der True-Zweig einer consteval-if-Anweisung (seit C++23) muss einen konstanten Ausdruck erzeugen; ein solcher Aufruf wird als Immediate-Aufruf bezeichnet.
consteval int sqr(int n) { return n*n; } constexpr int r = sqr(100); // OK int x = 100; int r2 = sqr(x); // Fehler: Aufruf erzeugt keine Konstante consteval int sqrsqr(int n) { return sqr(sqr(n)); // An dieser Stelle kein konstanter Ausdruck, aber OK } constexpr int dblsqr(int n) { return 2 * sqr(n); // Fehler: Umschließende Funktion ist nicht consteval // und sqr(n) ist keine Konstante }
Ein Identifikatorausdruck , der eine Immediate-Funktion bezeichnet, darf nur innerhalb eines Teilausdrucks eines Immediate-Aufrufs oder innerhalb eines Immediate-Funktionskontexts erscheinen (d.h. eines oben erwähnten Kontexts, in dem ein Aufruf einer Immediate-Funktion kein konstanter Ausdruck sein muss). Ein Zeiger oder eine Referenz auf eine Immediate-Funktion kann erstellt werden, darf jedoch die Auswertung konstanter Ausdrücke nicht verlassen:
consteval int f() { return 42; } consteval auto g() { return &f; } consteval int h(int (*p)() = g()) { return p(); } constexpr int r = h(); // OK constexpr auto e = g(); // ungültig: Ein Zeiger auf eine Immediate-Funktion ist // kein zulässiges Ergebnis eines konstanten Ausdrucks
Hinweise
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_consteval
|
201811L
|
(C++20) | Unmittelbare Funktionen |
202211L
|
(C++23)
(DR20) |
Propagierung von consteval nach oben |
Schlüsselwörter
Beispiel
#include <iostream> // Diese Funktion könnte zur Kompilierzeit ausgewertet werden, falls die Eingabe // zur Kompilierzeit bekannt ist. Andernfalls wird sie zur Laufzeit ausgeführt. constexpr unsigned factorial(unsigned n) { return n < 2 ? 1 : n * factorial(n - 1); } // Mit consteval erzwingen wir, dass die Funktion zur Kompilierzeit ausgewertet wird. consteval unsigned combination(unsigned m, unsigned n) { return factorial(n) / factorial(m) / factorial(n - m); } static_assert(factorial(6) == 720); static_assert(combination(4, 8) == 70); int main(int argc, const char*[]) { constexpr unsigned x{factorial(4)}; std::cout << x << '\n'; [[maybe_unused]] unsigned y = factorial(argc); // OK // unsigned z = combination(argc, 7); // Fehler: 'argc' ist kein konstanter Ausdruck }
Ausgabe:
24
Siehe auch
constexpr
Spezifizierer
(C++11)
|
gibt an, dass der Wert einer Variable oder Funktion zur Kompilierzeit berechnet werden kann |
constinit
Spezifizierer
(C++20)
|
stellt sicher, dass eine Variable eine statische Initialisierung hat, d.h. Nullinitialisierung und Konstanteninitialisierung |
| Konstantenausdruck | definiert einen Ausdruck der zur Kompilierzeit ausgewertet werden kann |