可以在常量表达式中下标字符串文字吗? [英] Can a string literal be subscripted in a constant expression?

查看:130
本文介绍了可以在常量表达式中下标字符串文字吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是有效的,因为允许使用 constexpr 表达式取指向使用constexpr定义的非易失性对象的文字类型的glvalue的值,或者指向这样一个对象的子对象(§5.19/ 2):

  constexpr char str [] =你好,世界; 
constexpr char e = str [1];但是,字符串文字似乎不适合这种描述:


$ b

  constexpr char e =hello,world[1]; //错误:literal不是constexpr 

2.14.5 / 8描述了字符串文字的类型: / p>


普通字符串文字和UTF-8字符串文字也称为窄字符串文字。一个窄字符串文字具有类型array of n const char,其中n是下面定义的字符串的大小,并且具有静态存储持续时间。


看起来这个类型的对象可以被索引,如果只是临时的,而不是静态存储持续时间(5.19 / 2,紧接着上面的代码片段之后):


[ constexpr 允许] ...一个字面值类型的glvalue,指的是一个非易失性临时对象的生存期尚未结束,用常量表达式初始化


这是特别奇怪的,因为获取临时对象的左值通常欺骗。我想这个规则适用于引用类型的函数参数,如

  constexpr char get_1(char const(& str) [6])
{return str [1]; }

constexpr char i = get_1({'y','i','k','e','s','\0' // OK
constexpr char e = get_1(hello); // error:string literal not temporary

对于值得的,GCC 4.7接受 get_1(hello),但拒绝hello[1] ,因为._0'的值不能用于常量表达式... hello[1] 是可接受的案例标签或数组边界。



我在这里分割一些标准的头发...分析是否正确,这个功能有没有一些设计意图?



哦...有一些动机。看起来这种表达式是在预处理器中使用查找表的唯一方法。例如,这引入了一个被忽略的代码块,除非 SOME_INTEGER_FLAG 是1或5,并且如果大于6则导致诊断:

  #if\0\1\0\0\0\1[SOME_INTEGER_FLAG] 



这个结构对C ++ 11来说是新的。

解决方案

目的是这个工作和段落,说明左值到右值转换是有效的修改了一个注释,说明引用字符串文字的子对象的左值是一个常量整数对象用常量表达式初始化(​​这被描述为允许的情况之一)在后C ++ 11草稿中。



您对于在预处理器中的使用的评论看起来很有趣,但我不确定是否打算工作。我第一次听到这个消息。


This is valid, because a constexpr expression is allowed to take the value of "a glvalue of literal type that refers to a non-volatile object defined with constexpr, or that refers to a sub-object of such an object" (§5.19/2):

constexpr char str[] = "hello, world";
constexpr char e = str[1];

However, it would seem that string literals do not fit this description:

constexpr char e = "hello, world"[1]; // error: literal is not constexpr

2.14.5/8 describes the type of string literals:

Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type "array of n const char", where n is the size of the string as defined below, and has static storage duration.

It would seem that an object of this type could be indexed, if only it were temporary and not of static storage duration (5.19/2, right after the above snippet):

[constexpr allows lvalue-to-rvalue conversion of] … a glvalue of literal type that refers to a non-volatile temporary object whose lifetime has not ended, initialized with a constant expression

This is particularly odd since taking the lvalue of a temporary object is usually "cheating." I suppose this rule applies to function arguments of reference type, such as in

constexpr char get_1( char const (&str)[ 6 ] )
    { return str[ 1 ]; }

constexpr char i = get_1( { 'y', 'i', 'k', 'e', 's', '\0' } ); // OK
constexpr char e = get_1( "hello" ); // error: string literal not temporary

For what it's worth, GCC 4.7 accepts get_1( "hello" ), but rejects "hello"[1] because "the value of ‘._0’ is not usable in a constant expression"… yet "hello"[1] is acceptable as a case label or an array bound.

I'm splitting some Standardese hairs here… is the analysis correct, and was there some design intent for this feature?

EDIT: Oh… there is some motivation for this. It seems that this sort of expression is the only way to use a lookup table in the preprocessor. For example, this introduces a block of code which is ignored unless SOME_INTEGER_FLAG is 1 or 5, and causes a diagnostic if greater than 6:

#if "\0\1\0\0\0\1"[ SOME_INTEGER_FLAG ]

This construct would be new to C++11.

解决方案

The intent is that this works and the paragraphs that state when an lvalue to rvalue conversion is valid will be amended with a note that states that an lvalue that refers to a subobject of a string literal is a constant integer object initialized with a constant expression (which is described as one of the allowed cases) in a post-C++11 draft.

Your comment about the use within the preprocessor looks interesting but I'm unsure whether that is intended to work. I hear about this the first time at all.

这篇关于可以在常量表达式中下标字符串文字吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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