2015-03-25 40 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

相關問題