为什么必须在运行时构建字符串? [英] Why must a string be constructed at run-time?
问题描述
可以创建C-Strings或 std :: string
作为 constexpr
,或者必须在运行时创建-time?
使用gcc 4.9.2我可以这样做:
constexpr const char foo [] =blee;
(可悲的是2013年11月客户技术预览不允许Visual Studio支持这个:http://stackoverflow.com/a/29255013/2642059 )
但是即使用gcc 4.9.2我不能这样做:
constexpr const std :: string foo =blee
我得到错误:
错误:constexpr变量'foo'的类型'const string {aka const std :: basic_string< char>}'
不是文字
constexpr const std :: string foo =blee;
^
注意:'std :: basic_string< char>'不是字面值,因为:
class basic_string
^
note:'std :: basic_string< char& '有一个非平凡的析构函数
但我想更多的澄清为什么 a std :: string
不是文字。也就是说:为什么必须在运行时构建字符串?
正如指出的,这个问题可以部分地回答: 是否可以在constexpr中使用std :: string?但它不触及为什么 std :: string
不能是一个文字,这是问题的核心。
建议使用一个 constexpr 字符串:编译时字符串:std :: string_literal ,它说:
< blockquote>
std :: string_literal
(如 std :: string
)的目的是to
为处理文本提供了一个方便的实用程序。与
std :: string
不同, std :: string_literal
的实例化是
因此可以在compiletime使用。也就是说,它可以是 constexpr
对象的类型
,它可以是参数的类型,
返回值或局部变量a constexpr
function
std :: string 不是一个字符类型
。$ c> std :: string 一个文字类型?
我们得到一个提示为什么从上面的提案为什么这不可能:
这需要一个大规模的核心语言改变来实现
像编译时可用的动态内存,或者使某些
像VLA / ARB,并允许它们在文字类型。鉴于Rapperswil Evolution不仅对N4025(运行时大小的类
)的暴力
负面反应,而且任何与VLA / ARBs类似的任何东西,我们
可以预期这不会发生,所以这个想法是一个
的非开始。
std :: string
为什么constexpr不能应用于std :: string,但可以使用char
B> constexpr
适用于某个物件,应套用至不适用于 std :: string
,但适用于 const char
的数组。从草案C ++ 11标准部分 7.1.5
[dcl.constexpr] (强调我的前进) :
一个
constexpr
在对象声明中使用的说明符声明
对象作为const
。这样的对象应该有文字类型,并且
必须初始化。如果它是通过构造函数调用初始化的,那么
调用应该是一个常量表达式(5.19)。 [...]
和 3.9
如果是,则类型是文字类型:
并包括:
- 或
- 一个文字类型数组
>算术类型是标量类型,包括 char ,其中包括 const char
和类:
一个类类型(第9条),具有以下所有属性:
- 它有一个简单的析构函数
- 在非静态数据成员(如果有的话)的括号或均值初始化器中是常数表达式(5.19),
- 它是一个聚合类型)或至少有一个
constexpr
不是复制或移动
构造函数的构造函数或构造函数模板和
- 其所有非 -
static
数据成员和基类都是文字类型。
< blockquote>
std :: string
不符合该条件。Can C-Strings or
std::string
s be created asconstexpr
or must they be created at run-time?With gcc 4.9.2 I can do this:
constexpr const char foo[] = "blee";
(Sadly the November 2013 Customer Technology Preview does not allow Visual Studio to support this: http://stackoverflow.com/a/29255013/2642059)
But even with gcc 4.9.2 I cannot do this:
constexpr const std::string foo = "blee";
I get the error:
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
But I would like more clarification on why a
std::string
is not a literal. That is to say: Why must a string be constructed at run-time?As pointed out this question can partially be answered by this: Is it possible to use std::string in a constexpr? but it does not touch on the why
std::string
can not be a literal which is core to the question.解决方案There is a proposal for a constexpr string: Compile-Time String: std::string_literal and it says:
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
functionwhich also confirms that indeed
std::string
is not a literal type.So why not just make
std::string
a literal type?We get a hint why from the proposal above why this not possible:
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
requires dynamic memory which is not available at compile time.Why constexpr can not be applied to std::string but can to array of char
constexpr
applied to an object shall be applied to a literal type which does not apply tostd::string
but applies to an array ofconst char
. From the draft C++11 standard section7.1.5
[dcl.constexpr] (emphasis mine going forward):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). […]and from section
3.9
[basic.types]:A type is a literal type if it is:
and includes:
- a scalar type; or
- an array of literal type
Arithmetic types are scalar types and include char, which covers the array of
const char
and for classes:
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
does not meet that criteria.这篇关于为什么必须在运行时构建字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!