consteval-Spezifizierer (seit C++20)
consteval- gibt an, dass eine Funktion eine Sofortfunktion ist, d. h. jeder Aufruf der Funktion muss eine Konstante zur Kompilierzeit erzeugen
Inhalt |
[bearbeiten] Erklärung
Der consteval-Spezifizierer deklariert eine Funktion oder eine Funktio-nalvorlage als Sofortfunktion, d. h. jeder potenziell ausgewertete Aufruf der Funktion muss (direkt oder indirekt) eine Konstante zur Kompilierzeit erzeugen.
Eine Sofortfunktion ist eine constexpr-Funktion, vorbehaltlich ihrer jeweiligen Anforderungen. Genau wie constexpr impliziert ein consteval-Spezifizierer inline. Er kann jedoch nicht auf Destruktoren, Allokations- oder Deallokationsfunktionen angewendet werden.
Eine Funktion oder eine Funktionsvorlage, die consteval angibt, darf nicht gleichzeitig constexpr angeben, und alle erneuten Deklarationen dieser Funktion oder Funktionsvorlage müssen ebenfalls consteval angeben.
Eine potenziell ausgewertete In-vocati-on einer Sofortfunktion, deren innerster Nicht-Block-Scope kein Funktionsparameter-Scope einer Sofortfunktion oder der true-Zweig einer consteval-if-Anweisung(seit C++23) ist, muss eine konstante Aus-druck erzeugen; eine solche In-vocati-on wird als sofortige In-vocati-on bezeichnet.
consteval int sqr(int n) { return n*n; } constexpr int r = sqr(100); // OK int x = 100; int r2 = sqr(x); // Error: Call does not produce a constant consteval int sqrsqr(int n) { return sqr(sqr(n)); // Not a constant expression at this point, but OK } constexpr int dblsqr(int n) { return 2 * sqr(n); // Error: Enclosing function is not consteval // and sqr(n) is not a constant }
Ein Bezeichner-Ausdruck, der auf eine Sofortfunktion verweist, darf nur innerhalb eines Teilausdrucks einer sofortigen In-vocati-on oder innerhalb eines sofortigen Funktionskontextes (d. h. eines oben erwähnten Kontexts, in dem ein Aufruf einer Sofortfunktion keine Konstante sein muss) erscheinen. Ein Zeiger oder eine Referenz auf eine Sofortfunktion kann genommen werden, kann aber die Auswertung von konstanten Aus-drücken 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(); // ill-formed: a pointer to an immediate function is // not a permitted result of a constant expression
[bearbeiten] Hinweise
| Feature-Testmakro | Wert | Std | Feature |
|---|---|---|---|
__cpp_consteval |
201811L |
(C++20) | Sofortfunktionen |
202211L |
(C++23) (DR20) |
consteval nach oben weitergeben |
[bearbeiten] Schlüsselwörter
[bearbeiten] Beispiel
#include <iostream> // This function might be evaluated at compile-time, if the input // is known at compile-time. Otherwise, it is executed at run-time. constexpr unsigned factorial(unsigned n) { return n < 2 ? 1 : n * factorial(n - 1); } // With consteval we enforce that the function will be evaluated at compile-time. 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); // error: 'argc' is not a constant expression }
Ausgabe
24
[bearbeiten] Siehe auch
constexpr-Spezifizierer(C++11) |
gibt an, dass der Wert einer Variablen oder Funktion zur Kompilierzeit berechnet werden kann |
constinit-Spezifizierer(C++20) |
stellt sicher, dass eine Variable eine statische Initialisierung hat, d. h. Null-Initialisierung und konstante Initialisierung |
| Konstanter Ausdruck | definiert einen Ausdruck, der zur Kompilierzeit ausgewertet werden kann |