¿Por qué debe construirse una cadena en tiempo de ejecución? [duplicar]
Esta pregunta ya tiene una respuesta aquí:
- ¿Es posible usar std::string en un constexpr? 3 respuestas
¿Se pueden crear cadenas C o std::string
como constexpr
o deben crearse en tiempo de ejecución?
Con gcc 4.9.2 puedo hacer esto:
constexpr const char foo[] = "blee";
(Lamentablemente, la Vista Previa de la tecnología del Cliente de noviembre de 2013 no permite que Visual Studio apoyo esto: https://stackoverflow.com/a/29255013/2642059)
Pero incluso con gcc 4.9.2 no puedo hacer esto:
constexpr const std::string foo = "blee";
Obtengo el error:
error: the type 'const string {aka const std::basic_string<char>}' of constexpr variable 'foo'
is not literal
constexpr const std::string foo = "blee";
^
note: 'std::basic_string<char>' is not literal because:
class basic_string
^
note: 'std::basic_string<char>' has a non-trivial destructor
Pero me gustaría más aclaración sobre por qué a std::string
no es literal. Es decir: ¿Por qué debe construirse una cadena en tiempo de ejecución?
Como se ha señalado, esta pregunta puede responderse parcialmente con esto: ¿Es posible usar std::string en un constexpr? pero no toca la ¿por qué std::string
no puede ser un literal que es el núcleo de la pregunta.
2 answers
Hay una propuesta para una cadena constexpr : Cadena en tiempo de compilación: std:: string_literal y dice:
El propósito de
std::string_literal
, al igual questd::string
, es proporcione una utilidad conveniente para trabajar con texto. A diferencia destd::string
, una instanciación destd::string_literal
es un literal tipo y así se puede utilizar en tiempo de compilación. Es decir, puede ser el tipo de un objetoconstexpr
, y puede ser el tipo de un parámetro, valor devuelto o variable local de unconstexpr
function
Que también confirma que efectivamente std::string
no es un tipo literal.
Entonces, ¿por qué no simplemente hacer std::string
un tipo literal?
Obtenemos una pista de por qué de la propuesta anterior por qué esto no es posible:
Esto requeriría un cambio masivo del lenguaje central para hacer algo como la memoria dinámica disponible en tiempo de compilación, o para hacer algo como VLA / ARB y permitirlos en tipos literales. Dada la violencia reacción negativa de Rapperswil Evolución no solo a N4025 (Clases de tamaño de Tiempo de ejecución), pero cualquier cosa que se asemeje vagamente a VLA / ARBs, puede esperar que esto no suceda en el corto plazo, por lo que esta idea es un sin principio.
std::string
requiere memoria dinámica que no está disponible en tiempo de compilación.
Por qué constexpr no se puede aplicar a std:: string sino a array de char
constexpr
aplicado a un objeto se aplicará a un tipo literal que no se aplica a std::string
, pero se aplica a una matriz de const char
. Del borrador de la sección estándar de C++117.1.5
[dcl.constexpr] (énfasis mío en el futuro):
Un especificador
constexpr
utilizado en una declaración de objeto declara el objeto comoconst
. Tal objeto tendrá el tipo literal y ser inicializado. Si es inicializado por una llamada de constructor, que call será una expresión constante (5.19). […]
Y de la sección 3.9
[básico.tipos]:
Un tipo es un tipo literal si es:
E incluye:
- un tipo escalar; o
- una matriz de tipo literal
Los tipos aritméticos son tipos escalares e incluyen char , que cubre la matriz de const char
Y para las clases:
Un tipo de clase (Cláusula 9) que tiene todas las propiedades siguientes:
- tiene un destructor trivial,
- cada llamada de constructor y expresión completa en los inicializadores brace-or-equal para miembros de datos no estáticos (si los hay) es una expresión constante (5.19),
- es un tipo agregado (8.5.1) o tiene al menos un constructor o plantilla de constructor
constexpr
que no es una copia o movimiento constructor , y- todos sus miembros de datos y clases base no-
static
son de tipos literales.
std::string
no cumple con ese criterio.
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
2015-03-30 20:49:12
No puedes usar constexpr, porque std::string no tiene un destructor trivial . Compruebe los requisitos en cppreference.
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
2015-03-25 12:19:12