为什么必须在 运行 时间构造一个字符串?
Why must a string be constructed at run-time?
C 字符串或 std::string
可以创建为 constexpr
还是必须在 运行 时创建?
使用 gcc 4.9.2 我可以做到这一点:
constexpr const char foo[] = "blee";
(遗憾的是,2013 年 11 月的客户技术预览不允许 Visual Studio 支持此:)
但即使使用 gcc 4.9.2 我也不能这样做:
constexpr const std::string foo = "blee";
我收到错误:
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
但我想进一步说明 为什么 std::string
不是文字。也就是说:为什么一定要在运行时构造一个字符串?
正如所指出的,这个问题可以部分地通过以下方式回答:Is it possible to use std::string in a constexpr? 但它没有触及为什么 std::string
不能是问题的核心文字。
你不能使用 constexpr,因为 std::string 没有平凡的 destructor。检查 cppreference 的要求。
有人提议 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::string 但可以应用于 char 数组
应用于对象的 constexpr
应应用于 文字类型 不适用于 std::string
但适用于 [=21] 的数组=].来自 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
[basic.types]:
A type is a literal type if it is:
并包括:
- a scalar type; or
- an array of literal type
算术类型是标量类型,包括char,覆盖了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
不符合该标准。
C 字符串或 std::string
可以创建为 constexpr
还是必须在 运行 时创建?
使用 gcc 4.9.2 我可以做到这一点:
constexpr const char foo[] = "blee";
(遗憾的是,2013 年 11 月的客户技术预览不允许 Visual Studio 支持此:)
但即使使用 gcc 4.9.2 我也不能这样做:
constexpr const std::string foo = "blee";
我收到错误:
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
但我想进一步说明 为什么 std::string
不是文字。也就是说:为什么一定要在运行时构造一个字符串?
正如所指出的,这个问题可以部分地通过以下方式回答:Is it possible to use std::string in a constexpr? 但它没有触及为什么 std::string
不能是问题的核心文字。
你不能使用 constexpr,因为 std::string 没有平凡的 destructor。检查 cppreference 的要求。
有人提议 constexpr 字符串:Compile-Time String: std::string_literal 上面写着:
The purpose of
std::string_literal
, likestd::string
, is to provide a convenience utility for working with text. Unlikestd::string
, an instantiation ofstd::string_literal
is a literal type and so can be used at compiletime. That is, it may be the type of anconstexpr
object, and it may be the type of a parameter, return value or local variable of aconstexpr
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::string 但可以应用于 char 数组
应用于对象的constexpr
应应用于 文字类型 不适用于 std::string
但适用于 [=21] 的数组=].来自 C++11 标准草案 7.1.5
[dcl.constexpr]( 强调我的前进方向):
A
constexpr
specifier used in an object declaration declares the object asconst
. 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
[basic.types]:
A type is a literal type if it is:
并包括:
- a scalar type; or
- an array of literal type
算术类型是标量类型,包括char,覆盖了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
不符合该标准。