std::is_constant_evaluated
Definido en el archivo de encabezado <type_traits> | ||
constexprbool is_constant_evaluated()noexcept; | (desde C++20) | |
Detecta si una llamada a función ocurre en un contexto evaluado constante. Devuelve true
si la evaluación de la llamada ocurre dentro de la evaluación de una expresión o conversión que es manifestadamente evaluada constante; de lo contrario devuelve false
.
Las siguientes expresiones (incluyendo conversiones al tipo destino) son manifestadamente evaluadas constante:
- Donde se requiera gramaticalmente una expresión constante, incluyendo:
- límites de arrays;
- las dimensones en las expresiones new excepto la primera;
- longitudes de campos de bits;
- inicializadores de enumeración;
- alineaciones;
- expresiones
case
; - argumentos de plantilla sin tipo;
- expresiones en especificaciones noexcept;
- expresiones en declaraciones
static_assert
; - expresiones en especificadores
explicit
condicionales;
- condiciones de instrucciones constexpr if;
- invocaciones inmediatas;
- expresiones de restricción en definiciones de conceptos, requerimientos anidados, y cláusulas requiere;
- inicializadores de variables que son utilizables en expresiones constantes, incluyendo:
- inicializadores de variables constexpr;
- inicializadores de variables con tipo referencia o enteras calificadas-const, o tipo enumeración, cuando los inicializadores son expresiones constantes;
- inicializadores de variables estáticas (static) y locales al hilo (thread_local), cuando todas las subexpresiones de los inicializadores (incluyendo llamadas al constructor y conversiones implícitas) son expresiones constantes (es decir, cuando los inicializadores son inicializadores constantes).
Para probar las últimas dos condiciones, los compiladores pueden primero realizar una evaluación constante de prueba de los inicializadores. En este caso no se recomienda depender del resultado.
int y;constint a = std::is_constant_evaluated()? y :1;// Falla la evaluación constante de prueba. Se descarta la evaluación constante.// La variable a se inicializa dinámicamente con 1 constint b = std::is_constant_evaluated()?2: y;// La evaluación constante con std::is_constant_evaluation() == true tiene éxito.// La variable b se inicializa estáticamente con 2
Contenido |
[editar]Parámetros
(Ninguno)
[editar]Valor de retorno
true
si la evaluación de la llamada ocurre dentro de una expresión de conversión que es manifestadamente evaluada constante; de lo contrario, false
.
[editar]Notas
Cuando se usa directamente como la condición de la declaración static_assert
o de la instrucción constexpr if, std::is_constant_evaluated() siempre devuelve true.
[editar]Example
#include <type_traits>#include <cmath>#include <iostream> constexprdouble power(double b, int x){if(std::is_constant_evaluated()&&!(b ==0.0&& x <0)){// Un contexto de evaluación constante: Usar un algoritmo amigable con constexpr.if(x ==0)return1.0;double r =1.0, p = x >0? b :1.0/ b;auto u =unsigned(x >0? x :-x);while(u !=0){if(u &1) r *= p; u /=2; p *= p;}return r;}else{// Dejemos que el generador de código se las averigue.returnstd::pow(b, double(x));}} int main(){// Un contexto de expresión constanteconstexprdouble kilo = power(10.0, 3);int n =3;// No es una expresión constante porque n no puede convertirse a un rvalue// en un contexto de expresión constante// Equivalente a std::pow(10.0, double(n))double mucho = power(10.0, n); std::cout<< kilo <<" "<< mucho <<"\n";// (3)}
Salida:
1000 1000