可以在运行时创建C-String或std::string
s,constexpr
还是必须在运行时创建它们?
使用gcc 4.9.2,我可以这样做:
constexpr const char foo[] = "blee";
(遗憾的是,2013年11月客户技术预览版不允许Visual Studio支持此功能:https : //stackoverflow.com/a/29255013/2642059)
但是即使使用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
但是,我想进一步说明为什么astd::string
不是文字。就是说:为什么必须在运行时构造一个字符串?
正如指出的那样,可以通过以下方式部分地解决此问题:是否可以在constexpr中使用std :: string?但是它没有涉及为什么std::string
不能成为问题核心的文字。
有一个关于constexpr字符串的建议:编译时字符串:std :: string_literal,它说:
std::string_literal
类似于的目的std::string
是提供一种用于处理文本的便捷实用程序。与不同std::string
,的实例化std::string_literal
是一种文字类型,因此可以在编译时使用。也就是说,它可以是constexpr
对象的类型,也可以是参数的类型,返回值或constexpr
函数的局部变量
这也证实确实std::string
不是文字类型。
那么,为什么不只创建std::string
一个文字类型呢?
我们从上面的提案中得到了一个提示,为什么不能做到这一点:
这将需要进行大量的核心语言更改,以使诸如动态内存之类的东西在编译时可用,或者使诸如VLA / ARB之类的东西成为文字类型。鉴于Rapperswil Evolution不仅对N4025(运行时大小的类)而且对任何模糊不清的VLA / ARB都产生了强烈的负面反应,所以我们可以期望这种情况不会很快发生,因此这个主意是不可能的。
std::string
需要动态内存,该内存在编译时不可用。
为什么constexpr不能应用于std :: string但可以应用于char数组
constexpr
应用于对象的字面类型不适用于std::string
数组const char
。从C ++ 11标准草案7.1.5
[dcl.constexpr](强调我的前进)中:
constexpr
对象声明中使用的说明符将该对象声明为const
。这样的对象应具有文字类型并应进行初始化。如果它是通过构造函数调用初始化的,则该调用应为常量表达式(5.19)。[…]
并从3.9
[basic.types]部分开始:
类型是文字类型,如果是:
包括:
- 标量类型;或者
- 文字类型数组
算术类型是标量类型,包括char,它覆盖了const char
对于课程:
具有以下所有属性的类类型(第9条):
- 它有一个琐碎的破坏者,
- 非静态数据成员(如果有)中的括号或相等初始化程序中的每个构造函数调用和全表达式都是一个常量表达式(5.19),
- 它是聚合类型(8.5.1)或具有至少一个
constexpr
不是复制或移动构造函数的构造函数或构造函数模板,并且- 它的所有非
static
数据成员和基类都是文字类型。
std::string
不符合该条件。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句