【发布时间】:2014-11-11 04:47:30
【问题描述】:
我写了下面的例子:
#include <iostream>
volatile int&& bar()
{
return 1;
}
int main()
{
const int& i = bar(); //error: binding of reference to type 'const int'
//to a value of type 'volatile int' drops qualifiers
}
但如果我们将int&& 替换为int,它就可以正常工作:
#include <iostream>
volatile int bar()
{
return 1;
}
int main()
{
const int& i = bar(); //OK
}
这并不完全清楚。标准所说的是 (8.5.3/5 [dcl.init.ref]):
对类型“cv1 T1”的引用由类型表达式初始化 “cv2 T2”如下:
——如果引用是左值引用并且 初始化表达式
是一个左值(但不是位域),并且“cv1 T1”与“cv2 T2”是引用兼容的,或者
具有类类型(即 T2 是类类型),其中 T1 与 T2 没有引用相关, 并且可以转换为“cv3 T3”类型的左值,其中“cv1 T1”与 “cv3 T3” 108(通过枚举适用的转换函数选择此转换 (13.3.1.6)并通过重载决议(13.3)选择最好的一个,然后 引用绑定到第一个中的初始化表达式左值 情况和第二种情况下转换的左值结果 (或者,在任何一种情况下,到适当的基类子对象 目的)。
[...]
— 否则,引用应为对 a 的左值引用 非易失 const 类型(即 cv1 应为 const),或引用 应该是一个右值引用。
嗯,在第一个示例中,我们有一个 volatile int&& 类型的右值。 'otherwise' 案例适用于这两个示例。但是5/5 [expr] 说:
如果一个表达式最初的类型是“对 T 的引用”(8.3.2, 8.5.3),在进一步分析之前将类型调整为 T
所以,本质上我们有一个volatile int 类型的右值而不是volatile int&&,这意味着这两个示例应该以相同的方式工作。
【问题讨论】: