and c++ c++11 runtime compile-time constexpr

c++ - and - ¿Cuándo se evalúa una función constexpr en tiempo de compilación?



constexpr in c++ (2)

La función debe evaluarse en tiempo de compilación cuando se necesita una expresión constante.

El método más simple para garantizar esto es usar un valor constexpr o std::integral_constant :

constexpr auto result = POW(i, 2); // this should not compile since i is not a constant expression std::cout << result << std::endl;

o:

std::cout << std::integral_constant<int, POW(i, 2)>::value << std::endl;

o

#define POW_C(base, power) (std::integral_constant<decltype(POW((base), (power)), POW((base), (power))>::value) std::cout << POW_C(63, 2) << std::endl;

o

template<int base, int power> struct POW_C { static constexpr int value = POW(base, power); }; std::cout << POW_C<2, 63>::value << std::endl;

Dado que es posible llamar a una función declarada como constexpr durante el tiempo de ejecución, ¿bajo qué criterios decide el compilador calcularlo en tiempo de compilación o durante el tiempo de ejecución?

template<typename base_t, typename expo_t> constexpr base_t POW(base_t base, expo_t expo) { return (expo != 0 )? base * POW(base, expo -1) : 1; } int main(int argc, char** argv) { int i = 0; std::cin >> i; std::cout << POW(i, 2) << std::endl; return 0; }

En este caso, se desconoce en tiempo de compilación, que es probablemente la razón por la cual el compilador trata a POW () como una función normal que se llama en el tiempo de ejecución. Sin embargo, esta dinámica, por conveniente que parezca, tiene algunas implicaciones poco prácticas. Por ejemplo, ¿podría haber un caso en el que me gustaría que el compilador calcule una función constexpr durante el tiempo de compilación, donde el compilador decide tratarla como una función normal, cuando también habría funcionado durante el tiempo de compilación? ¿Hay algún escollo común conocido?


constexpr funciones constexpr se evaluarán en tiempo de compilación cuando todos sus argumentos sean expresiones constantes y el resultado también se utilice en una expresión constante. Una expresión constante podría ser un literal (como 42 ), un argumento de plantilla sin tipo (como N en la template<class T, size_t N> class array; ), una declaración de elemento enum (como Blue enum Color { Red, Blue, Green }; otra variable declarada constexpr , y así sucesivamente.

Se pueden evaluar cuando todos sus argumentos son expresiones constantes y el resultado no se usa en una expresión constante, pero eso depende de la implementación.