Namespaces
Variants

consteval specifier (since C++20)

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
  • 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

consteval

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