为什么必须在 运行 时间构造一个字符串?

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 compile­time. 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 non­starter.

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 不符合该标准。