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 - especifica que una función es una función inmediata , es decir, cada llamada a la función debe producir una constante en tiempo de compilación

Contenidos

Explicación

El especificador consteval declara una función o plantilla de función como una función inmediata , es decir, cada llamada potencialmente evaluada a la función debe (directa o indirectamente) producir una expresión constante en tiempo de compilación.

Una función inmediata es una función constexpr , sujeta a sus requisitos según sea el caso. Al igual que constexpr , un especificador consteval implica inline . Sin embargo, no puede aplicarse a destructores, funciones de asignación o funciones de desasignación.

Una declaración de función o plantilla de función que especifique consteval no puede especificar también constexpr , y cualquier redeclaración de esa función o plantilla de función también debe especificar consteval .

Una evaluación potencial de una función inmediata cuyo ámbito no-bloque más interno no es un ámbito de parámetro de función de una función inmediata o la rama verdadera de una sentencia if consteval (desde C++23) debe producir una expresión constante; dicha invocación se conoce como invocación inmediata .

consteval int sqr(int n)
{
    return n*n;
}
constexpr int r = sqr(100); // Correcto
int x = 100;
int r2 = sqr(x);            // Error: La llamada no produce una constante
consteval int sqrsqr(int n)
{
    return sqr(sqr(n));     // No es una expresión constante en este punto, pero es correcto
}
constexpr int dblsqr(int n)
{
    return 2 * sqr(n);      // Error: La función envolvente no es consteval
                            // y sqr(n) no es una constante
}

Un identificador de expresión que denota una función inmediata solo puede aparecer dentro de una subexpresión de una invocación inmediata o dentro de un contexto de función inmediata (es decir, un contexto mencionado anteriormente, en el cual una llamada a una función inmediata no necesita ser una expresión constante). Se puede tomar un puntero o referencia a una función inmediata pero no puede escapar de la evaluación de expresión constante:

consteval int f() { return 42; }
consteval auto g() { return &f; }
consteval int h(int (*p)() = g()) { return p(); }
constexpr int r = h();  // CORRECTO
constexpr auto e = g(); // incorrecto: un puntero a una función inmediata no es
                        // un resultado permitido de una expresión constante

Notas

Macro de prueba de características Valor Std Característica
__cpp_consteval 201811L (C++20) Funciones inmediatas
202211L (C++23)
(DR20)
Hacer que consteval se propague hacia arriba

Palabras clave

consteval

Ejemplo

#include <iostream>
// Esta función podría evaluarse en tiempo de compilación, si la entrada
// se conoce en tiempo de compilación. De lo contrario, se ejecuta en tiempo de ejecución.
constexpr unsigned factorial(unsigned n)
{
    return n < 2 ? 1 : n * factorial(n - 1);
}
// Con consteval forzamos a que la función se evalúe en tiempo de compilación.
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' no es una expresión constante
}

Salida:

24

Véase también

constexpr especificador (C++11) especifica que el valor de una variable o función puede calcularse en tiempo de compilación
constinit especificador (C++20) asegura que una variable tiene inicialización estática, es decir inicialización cero e inicialización constante
expresión constante define una expresión que puede evaluarse en tiempo de compilación