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?

Author: fredoverflow, 2012-11-12

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.

 237
Author: Howard Hinnant,
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

 64
Author: Pete Becker,
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.

 28
Author: Ajay yadav,
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:

  1. C++98 no tenía constexpr, por lo que la gente usó const.
  2. 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

 10
Author: Jnana,
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