Ответ 1
Существует предложение для строки constexpr: Строка времени компиляции: std:: string_literal и в ней говорится:
Цель
std::string_literal
, напримерstd::string
, состоит в том, чтобы предоставить удобную утилиту для работы с текстом. В отличие отstd::string
, экземплярstd::string_literal
является литералом типа и поэтому могут использоваться в compiletime. То есть, это может быть тип объектаconstexpr
, и это может быть тип параметра, возвращаемое значение или локальная переменная функцииconstexpr
что также подтверждает, что действительно std::string
не является литеральным типом.
Итак, почему бы просто не сделать std::string
литеральный тип?
Мы получаем подсказку, почему из предложения выше, почему это невозможно:
Это потребует значительного изменения основного языка, чтобы что-то сделать как динамическая память, доступная во время компиляции, или что-то сделать как VLA/ARB, и разрешать их в литеральных типах. Учитывая жестокость отрицательная реакция эволюции Rapperswil на не только N4025 (классы Runtime Size), но все, что смутно напоминает VLA/ARB, мы может ожидать, что это не произойдет в ближайшее время, поэтому эта идея неудачник.
std::string
требуется динамическая память, которая недоступна во время компиляции.
Почему constexpr не может быть применен к std::string, но может быть массив из char
constexpr
, применяемый к объекту, применяется к типу литерала, который не применяется к std::string
, но применяется к массиву const char
. Из стандартного раздела проекта С++ 11 7.1.5
[dcl.constexpr] (выделение в будущем):
A
constexpr
спецификатор, используемый в объявлении объекта, объявляет объект какconst
. Такой объект должен иметь буквальный тип и должен инициализируется. Если он инициализируется вызовом конструктора, это вызов должен быть постоянным выражением (5.19). [...]
и из раздела 3.9
[basic.types]:
Тип - это буквальный тип, если он:
и включает в себя:
- скалярный тип; или
- массив литералов типа
Арифметические типы являются скалярными типами и включают char, который охватывает массив const char
и для классов:
тип класса (раздел 9), который имеет все следующие свойства:
- имеет тривиальный деструктор,
- каждый вызов конструктора и полноэкранное выражение в элементарных элементах для нестатических данных (если они есть) является константным выражением (5.19),
- это тип агрегата (8.5.1) или имеет хотя бы один конструктор конструктора или конструктора
constexpr
, который не является копией или перемещением конструктор и- все элементы данных не
static
и базовые классы имеют литеральные типы.
std::string
не соответствует этим критериям.