2015-03-25 106 views
21

可以将C-Strings或std::string创建为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 

但我想对进行更多的说明,为什么 a std::string不是文字。也就是说:为什么必须在运行时构建一个字符串?

正如指出的这个问题可以部分回答这个:Is it possible to use std::string in a constexpr?但它并没有涉及为什么std::string不能成为问题的核心文字。

+0

对此问题感兴趣的人被[这个问题]的回答激怒了(http://stackoverflow.com/q/29166578/2642059)。 – 2015-03-25 12:13:46

+0

@juhist啊,我不知道我在搜索时错过了什么。所以答案是'std :: string'不是一个文字?为什么会这样?看起来像将const std :: string一个文字一样简单。 – 2015-03-25 12:17:13

+2

我想在其他答案中给出原因:因为'std :: basic_string'有一个不平凡的析构函数。 – juhist 2015-03-25 12:19:20

回答

26

有一个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但适用于一组const char。从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[碱性。类型]

A type is a literal type if it is:

,并包括:

  • a scalar type; or
  • an array of literal type

运算类型是标量类型,并包括,它覆盖的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不符合该标准。

+1

@downvoter请解释,任何技术错误,我错过了一个观点? – 2015-03-25 13:31:57

+1

@downvoter我也希望看到这个downvote删除,因为我觉得这熟练地回答了我问的问题。如果存在downvote的原因,我当然希望看到解释原因的评论。 – 2015-03-25 13:43:53

+1

我经常想知道是否有可能重载'std :: string'的构造函数,以便在使用字符串文字(或其他适用的常量表达式)调用足够短的时间来启用SSO的情况下, 'constexpr'版本会跳进去。 – 5gon12eder 2015-03-25 14:08:36

5

不能使用constexpr,因为std :: string没有小事destructor。检查cppreference的要求。

+2

你是说这是唯一的原因'std :: string'不是一个文字类型,有一个类的几个标准。 – 2015-03-25 12:33:01

相关问题