consteval
specifier
(since C++20)
-
-
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
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 |