const vs constexpr en las variables

¿Hay alguna diferencia entre las siguientes definiciones?

const double PI = 3.141592653589793; constexpr double PI = 3.141592653589793; 

Si no, ¿qué estilo se prefiere en C ++ 11?

Creo que hay una diferencia. Vamos a cambiarles el nombre para que podamos hablar sobre ellos más fácilmente:

 const double PI1 = 3.141592653589793; constexpr double PI2 = 3.141592653589793; 

Tanto PI1 como PI2 son constantes, lo que significa que no puede modificarlos. Sin embargo, solo PI2 es una constante en tiempo de comstackción. Se inicializará en tiempo de comstackción. PI1 se puede inicializar en tiempo de comstackción o tiempo de ejecución. Además, solo PI2 se puede usar en un contexto que requiere una constante de tiempo de comstackción. Por ejemplo:

 constexpr double PI3 = PI1; // error 

pero:

 constexpr double PI3 = PI2; // ok 

y:

 static_assert(PI1 == 3.141592653589793, ""); // error 

pero:

 static_assert(PI2 == 3.141592653589793, ""); // ok 

¿En cuanto a cuál debes usar? Use lo que se ajuste a sus necesidades. ¿Desea asegurarse de tener una constante de tiempo de comstackción que pueda usarse en contextos en los que se requiere una constante de tiempo de comstackción? ¿Desea poder inicializarlo con un cálculo realizado en tiempo de ejecución? Etc.

No hay diferencia aquí, pero importa cuando tienes un tipo que tiene un constructor.

 struct S { constexpr S(int); }; const S s0(0); constexpr S s1(1); 

s0 es una constante, pero no promete inicializarse en tiempo de comstackción. s1 está marcado constexpr , por lo que es una constante y, como el constructor de S también está marcado como constexpr , se inicializará en tiempo de comstackción.

Sobre todo, esto importa cuando la inicialización en tiempo de ejecución llevaría mucho tiempo y desea eliminar ese trabajo en el comstackdor, donde también consume mucho tiempo, pero no ralentiza el tiempo de ejecución del progtwig comstackdo.

constexpr indica un valor que es constante y conocido durante la comstackción.
const indica un valor que es solo constante; no es obligatorio saber durante la comstackción.

 int sz; constexpr auto arraySize1 = sz; // error! sz's value unknown at comstacktion std::array data1; // error! same problem constexpr auto arraySize2 = 10; // fine, 10 is a compile-time constant std::array data2; // fine, arraySize2 is constexpr 

Tenga en cuenta que const no ofrece la misma garantía que constexpr, porque los objetos const no necesitan inicializarse con valores conocidos durante la comstackción.

 int sz; const auto arraySize = sz; // fine, arraySize is const copy of sz std::array data; // error! arraySize's value unknown at comstacktion 

Todos los objetos constexpr son const, pero no todos los objetos const son constexpr.

Si desea que los comstackdores le garanticen que una variable tiene un valor que puede usarse en contextos que requieren constantes de tiempo de comstackción, la herramienta a la que debe llegar es constexpr, no const.

Una constante simbólica constexpr debe tener un valor conocido en tiempo de comstackción. Por ejemplo:

 constexpr int max = 100; void use(int n) { constexpr int c1 = max+7; // OK: c1 is 107 constexpr int c2 = n+7; // Error: we don't know the value of c2 // ... } 

Para manejar casos donde el valor de una “variable” que se inicializa con un valor que no se conoce en tiempo de comstackción pero que nunca cambia después de la inicialización, C ++ ofrece una segunda forma de constante (a const ). Por ejemplo:

 constexpr int max = 100; void use(int n) { constexpr int c1 = max+7; // OK: c1 is 107 const int c2 = n+7; // OK, but don't try to change the value of c2 // ... c2 = 7; // error: c2 is a const } 

Tales “variables const ” son muy comunes por dos razones:

  1. C ++ 98 no tenía constexpr, por lo que las personas usaban const .
  2. El elemento de la lista “Variables” que no son expresiones constantes (su valor no se conoce en tiempo de comstackción), pero que no cambian los valores después de la inicialización, en sí mismos son ampliamente útiles.

Referencia: “Progtwigción: Principios y práctica con C ++” de Stroustrup