c++ - como inicializar una referencia constexpr
c++11 reference (3)
Estoy tratando de inicializar una referencia constexpr
sin éxito. Lo intenté
#include <iostream>
constexpr int& f(int& x) // can define functions returning constexpr references
{
return x;
}
int main()
{
constexpr int x{20};
constexpr const int& z = x; // error here
}
pero estoy recibiendo un error de tiempo de compilación
error: la variable constexpr ''z'' debe inicializarse mediante una expresión constante
Bajando los resultados const
en
error: la vinculación de referencia al tipo ''int'' a un valor de tipo ''const int'' elimina los calificadores
aunque tuve la sensación de que constexpr
implica automáticamente const
para declaraciones de variables.
Así que mis preguntas son:
- ¿
constexpr
referenciasconstexpr
son útiles alguna vez? (es decir, "mejor" que las referenciasconst
) - En caso afirmativo, ¿cómo puedo definirlos efectivamente?
PD: He visto un par de preguntas relacionadas con la mía, como ¿Qué valores se pueden asignar a una referencia `constexpr`? , pero no creo que respondan a mis preguntas.
- ¿Las referencias constexpr son útiles alguna vez? (es decir, "mejor" que las referencias const)
Se garantiza que se inicien antes de que se inicie el programa, mientras que una referencia a const se puede inicializar durante la inicialización dinámica, después de que el programa comience a ejecutarse.
- En caso afirmativo, ¿cómo puedo definirlos efectivamente?
Una referencia constexpr
debe vincularse a una variable global, no a una local (o, más formalmente, debe vincularse a algo con una duración de almacenamiento estática).
Conceptualmente, una referencia es equivalente a tomar la dirección de la variable, y la dirección de una variable local no es una constante (incluso en main
que solo se puede llamar una vez y, por lo tanto, sus variables locales solo se inicializan una vez).
Como dice T.C. , el inicializador debe ser un objeto con una duración de almacenamiento estático.
N4140 / §5.19 / 4 Una expresión constante es una expresión constante de glvalue core cuyo valor se refiere a un objeto con una duración de almacenamiento estático [...]
N4140 / §7.1.5 / 9 Un especificador
constexpr
utilizado en una declaración de objeto declara que el objeto es const. Dicho objeto tendrá un tipo literal y se inicializará. [...] De lo contrario, o si se utiliza un especificadorconstexpr
en una declaración de referencia, cada expresión completa que aparezca en su inicializador será una expresión constante.
En N3337, la redacción es diferente.
Entonces, el problema es que una referencia constexpr debe vincularse a un objeto con una duración de almacenamiento estática, que se trata en el borrador del estándar C ++ 11: N3337 sección 5.19
[expr.const] ( énfasis mío ):
Una expresión de constante de referencia es una expresión de constante de núcleo lvalue que designa un objeto con una duración de almacenamiento estático o una función
El borrador del estándar C ++ 14: N3936 cambia la redacción:
Una expresión constante es una expresión constante de glvalue core cuyo valor se refiere a un objeto con una duración de almacenamiento estática o una función, o una expresión constante de prvalue core cuyo valor es un objeto donde, para ese objeto y sus subobjetos:
- cada miembro de datos no estáticos del tipo de referencia se refiere a un objeto con una duración de almacenamiento estática oa una función, y
- si el objeto o subobjeto es de tipo puntero, contiene la dirección de un objeto con duración de almacenamiento estático, la dirección más allá del final de dicho objeto (5.7), la dirección de una función o un valor de puntero nulo.
Así que cambiar la declaración de x
como así funcionaría:
constexpr static int x{20};