Существует предложение для constexpr строки: Compile-Time String: std::string_literal и он говорит:
The purpose of std::string_literal
, like std::string
, is to provide a convenience utility for working with text. Unlike std::string
, an instantiation of std::string_literal
is a literal type and so can be used at compiletime. That is, it may be the type of an constexpr
object, and it may be the type of a parameter, return value or local variable of a constexpr
function
который также подтверждает, что на самом деле std::string
не буквальным типа.
Так почему бы не просто сделать std::string
буквального типа?
Мы получаем намек, почему из предложения выше, почему это не представляется возможным:
This would require a massive core language change to make something like dynamic memory available at compile-time, or to make something like VLA/ARB and permit them in literal types. Given the violently negative reaction of Rapperswil Evolution to not only N4025 (Classes of Runtime Size), but anything that vaguely resembles VLA/ARBs, we can expect this not to happen any time soon, so this idea is a nonstarter.
std::string
требует динамической памяти, которая не доступна во время компиляции.
Почему constexpr не может быть применена к STD :: строки, но может в массив полукокса
constexpr
применяется к объекту, должен быть применен к буквальному типу, который не относится к std::string
но относится к массив const char
. Из проекта C++ 11 стандартной секции 7.1.5
[dcl.constexpr] (курсив мой идти вперед):
A constexpr
specifier used in an object declaration declares the object as const
. Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant expression (5.19). […]
и из раздела 3.9
[основной.Типы]:
A type is a literal type if it is:
и включает в себя:
- a scalar type; or
- an array of literal type
Арифметические типы являются скалярными типами и включают в себя символ, который охватывает массив const char
и для классов:
a class type (Clause 9) that has all of the following properties:
- it has a trivial destructor,
- every constructor call and full-expression in the brace-or-equal-initializers for non-static data members (if any) is a constant expression (5.19),
- it is an aggregate type (8.5.1) or has at least one
constexpr
constructor or constructor template that is not a copy or move constructor, and
- all of its non-
static
data members and base classes are of literal types.
std::string
не соответствует этим критериям.
К кому это может относиться, моя заинтересованность в этом была вызвана ответами на [этот вопрос] (http://stackoverflow.com/q/29166578/2642059). –
@juhist А, я не знаю, как я пропустил это, когда искал. Итак, ответ заключается в том, что 'std :: string' не является литералом? Почему это так? Похоже, было бы просто сделать 'const std :: string' литералом. –
Я думаю, что причина дана в другом ответе: потому что «std :: basic_string» имеет нетривиальный деструктор. – juhist