由于字符串文字被视为左值,为什么绑定左值引用必须是const? [英] Since a string literal is considered an lvalue, why must the binding lvalue reference be const?

查看:84
本文介绍了由于字符串文字被视为左值,为什么绑定左值引用必须是const?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道已经有一些与此主题类似的主题(例如

I know there are topics that are similar to this one already (such as this).

本主题中给出的示例是这样的:

The example given in this topic was this:

std::string & rs1 = std::string();

很显然,std :: string()是一个右值.但是,我的问题是为什么s1合法而s2不合法?

Clearly, that std::string() is an rvalue. However, my question is why is s1 legal while s2 is not?

const std::string& s1 = "String literal";
std::string& s2 = "String literal";

该标准明确指出字符串文字是左值(这是可以理解的,因为从技术上讲,它们是幕后的const char *).但是,当我编译s2时,得到以下信息:

The standard clearly states that string literals are lvalues (which is understandable since they are technically const char* behind the scenes). When I compile s2 though, I get the following:

prog.cpp:4:19: error: invalid initialization of non-const reference of type
'std::string& {aka std::basic_string<char>&}' from an rvalue of type
'const char*' std::string& s2 = "String literal";

我知道左值和右值的标准定义是互斥的,因此这可能是编译器的错误吗?在此示例中,我使用的是gcc 4.9.2.文字确实是xvalue的情况也是这种情况之一吗?

I understand that the standard definition of lvalues and rvalues are mutually exclusive, so is this potentially an error with the compiler? I'm using gcc 4.9.2 in this example. Would this also be one of the cases where the literal is really an xvalue?

推荐答案

问题是字符串文字不是 std :: string 类型或其子类-它是
类型 char const [N] .因此,初始化程序的类型与引用的目标类型与引用不兼容,并且必须创建一个临时并将其绑定到引用.

The problem is that a string literal is not of type std::string or subclass thereof - it is of type
char const[N]. Thus the type of the initializer is not reference compatible with the target type of the reference, and a temporary must be created and bound to the reference.

但是,临时对象不能绑定到非常量左值引用.IE.您的情况等同于

However, temporaries cannot be bound to non-const lvalue references. I.e. your case is equivalent to

std::string& s = std::string("Abcdefg");

即使根据您的说法,

也显然是错误的.

which is, even according to you, clearly ill-formed.

实际上,它不起作用的确切原因不是因为临时对象不能绑定到非常量左值引用,而是非常量左值引用的初始化程序要满足 char const [N] 在这种情况下无法满足要求,[dcl.init.ref]/5:

Actually the precise reason it doesn't work is not because temporaries cannot be bound to non-const lvalue references, but rather that the initializer of a non-const lvalue reference is subject to certain requirements that char const[N] cannot meet in this case, [dcl.init.ref]/5:

对类型" cv1 T1 "的引用由以下表达式初始化键入" cv2 T2 ",如下所示:

A reference to type "cv1 T1" is initialized by an expression of type "cv2 T2" as follows:

  • 如果引用是左值引用和初始值设定项表达式

  • If the reference is an lvalue reference and the initializer expression

  • 是左值(但不是位域),并且" cv1 T1 "与" cv2 "具有引用兼容性code> T2 "或
  • 具有类类型(即T2是类类型),其中T1与T2无关,并且可以隐式转换为左值类型为"cv3 T3",其中" cv1 T1 "与" cv3 T3 " 106 (此转换是通过列举适用的转换函数(13.3.1.6)并通过选择最佳的函数重载分辨率(13.3)),
  • is an lvalue (but is not a bit-field), and "cv1 T1" is reference-compatible with "cv2 T2" or
  • has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be implicitly converted to an lvalue of type "cv3 T3," where "cv1 T1" is reference-compatible with "cv3 T3"106(this conversion is selected by enumerating the applicable conversion functions (13.3.1.6) and choosing the best one through overload resolution (13.3)),

然后将引用绑定到初始化表达式中的左值第一种情况,并转换为左值结果第二种情况(或两种情况都适用)对象的子对象).

then the reference is bound to the initializer expression lvalue in the first case and to the lvalue result of the conversion in the second case (or, in either case, to the appropriate base class subobject of the object).

否则,引用应为对非易失性const类型的左值引用(即 cv1 为const),或引用应该是右值引用.

Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1 shall be const), or the reference shall be an rvalue reference.

  • [..]

106)这需要转换函数(12.3.2)返回引用类型.

这篇关于由于字符串文字被视为左值,为什么绑定左值引用必须是const?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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