const vs constexpr en 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?
4 answers
Creo que hay una diferencia. Vamos a cambiarles el nombre para que podamos hablar de 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 modificarlas. Sin embargo solamente PI2
es una constante en tiempo de compilación. It shall be initialized at compile time. PI1
puede inicializarse en tiempo de compilación o de ejecución. Además, sólo PI2
se puede usar en un contexto que requiere una constante en tiempo de compilación. Para 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 lo que debe utilizar? Utilice lo que satisfaga sus necesidades. ¿Desea asegurarse de que tiene una constante de tiempo de compilación que se puede usar en contextos donde se requiere una constante de tiempo de compilación? ¿Quieres ser capaz de inicializarlo con un cálculo realizado en tiempo de ejecución? Sucesivamente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-05 00:32:05
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 ser inicializada en tiempo de compilación. s1
está marcado constexpr
, por lo que es una constante y, debido a que el constructor de S
también está marcado constexpr
, se inicializará en tiempo de compilación.
Sobre todo esto importa cuando la inicialización en tiempo de ejecución consume mucho tiempo y desea enviar ese trabajo al compilador, donde también consume mucho tiempo, pero no ralentiza el tiempo de ejecución del programa compilado
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-12 16:04:41
Constexpr indica un valor que es constante y conocido durante la compilación.
const indica un valor que es solo constante; no es obligatorio saberlo durante la compilación.
int sz;
constexpr auto arraySize1 = sz; // error! sz's value unknown at compilation
std::array<int, sz> data1; // error! same problem
constexpr auto arraySize2 = 10; // fine, 10 is a compile-time constant
std::array<int, arraySize2> data2; // fine, arraySize2 is constexpr
Tenga en cuenta que const no ofrece la misma garantía que constexpr, porque const los objetos no necesitan inicializarse con valores conocidos durante la compilación.
int sz;
const auto arraySize = sz; // fine, arraySize is const copy of sz
std::array<int, arraySize> data; // error! arraySize's value unknown at compilation
Todos los objetos constexpr son const, pero no todos los objetos const son constexpr.
Si desea que los compiladores garantizar que una variable tiene un valor que puede ser utilizado en contextos que requieren constantes en tiempo de compilación, la herramienta para alcanzar es constexpr, no const.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-17 10:36:41
A constexpr constante simbólica se le debe dar un valor que se conoce en tiempo de compilació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 compilació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:
- C++98 no tenía constexpr, por lo que la gente usó const.
- Listar "Variables" que no son expresiones constantes (su valor no se conoce en tiempo de compilación) pero no cambian los valores después de la inicialización es en sí misma ampliamente útil.
Referencia:" Programming: Principles and Practice Using C++ " por Stroustrup
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-28 01:09:53