我知道已经有一些与此主题类似的主题(例如this)。
本主题中给出的示例是这样的:
std::string & rs1 = std::string();
显然,std :: string()是一个右值。但是,我的问题是为什么s1合法而s2不合法?
const std::string& s1 = "String literal";
std::string& s2 = "String literal";
该标准明确指出字符串文字是左值(这是可以理解的,因为从技术上讲,它们是幕后的const char *)。当我编译s2时,得到以下信息:
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的情况之一吗?
问题是字符串文字不是类型std::string
或其子类,而是类型char const[N]
。因此,初始化程序的类型与引用的目标类型与引用不兼容,因此必须创建一个临时并将其绑定到引用。
但是,临时对象不能绑定到非常量左值引用。即您的情况相当于
std::string& s = std::string("Abcdefg");
即使根据您的说法,这显然也是错误的。
实际上,它不起作用的确切原因不是因为临时对象不能绑定到非常量左值引用,而是非常量左值引用的初始化程序受到某些char const[N]
无法满足的要求,在这种情况下[dcl。 init.ref] / 5:
参考输入“ CV1
T1
”是通过类型“的表达初始化CV2T2
”如下:
如果引用是左值引用和初始值设定项表达式
- 是左值(但不是位字段),以及“ CV1
T1
”是参考兼容“ CV2T2
”或- 具有类类型(即T2是类类型),其中T1与T2无关,并且可以隐式转换为类型为“ cv3 T3”的左值,其中“ cv1
T1
”与“ cv3 引用兼容”T3
” 106(通过枚举适用的转换函数(13.3.1.6)并通过过载分辨率选择最佳的转换函数(13.3)来选择此转换),然后,在第一种情况下将引用绑定到初始化程序表达式左值,在第二种情况下将引用绑定到转换的左值结果(或者在两种情况下都绑定到对象的适当基类子对象)。
否则,该引用应为对非易失性const类型的左值引用(即cv1为const),或者该引用应为右值引用。
- [..]
106)这需要返回参考类型的转换函数(12.3.2)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句