There is a proposal for a constexpr string: Compile-Time String: std::string_literal and it says:
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
which also confirms that indeed std::string
is not a literal type.
So why not just make std::string
a literal type?
We get a hint why from the proposal above why this not possible:
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
requires dynamic memory which is not available at compile time.
Why constexpr can not be applied to std::string but can to array of char
constexpr
applied to an object shall be applied to a literal type which does not apply to std::string
but applies to an array of const char
. From the draft C++11 standard section 7.1.5
[dcl.constexpr] (emphasis mine going forward):
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). […]
and from section 3.9
[basic.types]:
A type is a literal type if it is:
and includes:
- a scalar type; or
- an array of literal type
Arithmetic types are scalar types and include char, which covers the array of const char
and for classes:
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
does not meet that criteria.