为什么必须在运行时构建字符串? [英] Why must a string be constructed at run-time?

查看:159
本文介绍了为什么必须在运行时构建字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以创建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::strings be created as constexpr 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, 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

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

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 to std::string but applies to an array of const char. From the draft C++11 standard section 7.1.5 [dcl.constexpr] (emphasis mine going forward):

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). […]

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆