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 - spécifie qu'une fonction est une fonction immédiate , c'est-à-dire que chaque appel à la fonction doit produire une constante de compilation

Table des matières

Explication

Le spécificateur consteval déclare une fonction ou un modèle de fonction comme étant une fonction immédiate , c'est-à-dire que tout appel potentiellement évalué à la fonction doit (directement ou indirectement) produire une expression constante au moment de la compilation.

Une fonction immédiate est une fonction constexpr , soumise à ses exigences selon le cas. Comme constexpr , un spécificateur consteval implique inline . Cependant, il ne peut pas être appliqué aux destructeurs, fonctions d'allocation ou fonctions de désallocation.

Une déclaration de fonction ou de modèle de fonction spécifiant consteval ne peut pas non plus spécifier constexpr , et toute redéclaration de cette fonction ou de ce modèle de fonction doit également spécifier consteval .

Une évaluation potentielle d'une fonction immédiate dont la portée non-bloc la plus interne n'est pas une portée de paramètre de fonction d'une fonction immédiate ou la branche vraie d'une instruction if consteval (depuis C++23) doit produire une expression constante ; une telle invocation est appelée invocation immédiate .

consteval int sqr(int n)
{
    return n*n;
}
constexpr int r = sqr(100); // Correct
int x = 100;
int r2 = sqr(x);            // Erreur : L'appel ne produit pas une constante
consteval int sqrsqr(int n)
{
    return sqr(sqr(n));     // Pas une expression constante à ce stade, mais correct
}
constexpr int dblsqr(int n)
{
    return 2 * sqr(n);      // Erreur : La fonction englobante n'est pas consteval
                            // et sqr(n) n'est pas une constante
}

Une expression d'identifiant qui désigne une fonction immédiate ne peut apparaître que dans une sous-expression d'un appel immédiat ou dans un contexte de fonction immédiate (c'est-à-dire un contexte mentionné ci-dessus, dans lequel un appel à une fonction immédiate n'a pas besoin d'être une expression constante). Un pointeur ou une référence vers une fonction immédiate peut être pris mais ne peut échapper à l'évaluation d'expression constante :

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(); // incorrect : un pointeur vers une fonction immédiate n'est
                        // pas un résultat autorisé d'une expression constante

Notes

Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_consteval 201811L (C++20) Fonctions immédiates
202211L (C++23)
(DR20)
Faire propager consteval vers le haut

Mots-clés

consteval

Exemple

#include <iostream>
// Cette fonction peut être évaluée à la compilation, si l'entrée
// est connue à la compilation. Sinon, elle est exécutée à l'exécution.
constexpr unsigned factorial(unsigned n)
{
    return n < 2 ? 1 : n * factorial(n - 1);
}
// Avec consteval nous forçons l'évaluation de la fonction à la compilation.
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); // erreur : 'argc' n'est pas une expression constante
}

Sortie :

24

Voir aussi

constexpr spécificateur (C++11) spécifie que la valeur d'une variable ou fonction peut être calculée à la compilation
constinit spécificateur (C++20) affirme qu'une variable a une initialisation statique, c'est-à-dire initialisation à zéro et initialisation constante
expression constante définit une expression qui peut être évaluée à la compilation