N4527 8.5.3 [dcl.init.ref]
5类型“cv1 T1”的引用由“cv2 T2”类型的表达式初始化,如下所示:
(5.1) - [...]
(5.1.1) - [...]
(5.1.2) - [...]
(5.2) - 否则,引用应是对非易失性const类型的左值引用(即,cv1应为 const),或引用应为右值引用。
(5.2.1) - 如果是初始化表达式
(5.2.1.1) - 是xvalue(但不是位字段),类prvalue,数组prvalue或函数lvalue和“cv1 T1” 与“cv2 T2”或
引用兼容(5.2.1.2) - 具有类类型(即,T2是类类型),其中T1与T2不是引用相关的,并且可以是 转换为类型为“cv3 T3”的xvalue,类prvalue或函数左值,其中“cv1 T1”为 参考兼容“cv3 T3”(见13.3.1.6),
然后引用绑定到第一种情况下的初始化表达式的值和 第二种情况下转换的结果(或者,在任何一种情况下,转换为适当的基类) 子对象)。
(5.2.2) - 否则:
(5.2.2.1) - 如果T1或T2是类类型且T1与T2无参考相关,则用户定义的转换 被认为是使用userdefined对“cv1 T1”类型的对象进行复制初始化的规则 转换(8.5,13.3.1.4,13.3.1.5);如果相应的非参考拷贝初始化将是不正确的,则程序是不正确的。调用转换的结果 然后,如针对非参考拷贝初始化所描述的,函数用于直接初始化 参考资料。对于此直接初始化,不考虑用户定义的转换。
(5.2.2.2) - 否则,创建临时类型为“cv1 T1”并从初始化程序复制初始化(8.5) 表达。然后将引用绑定到临时。
如果T1与T2有参考关系:
(5.2.2.3) - cv1应与cv2具有相同的cv资格,或者比cv2更高的cv资格;和
(5.2.2.4) - 如果引用是右值引用,则初始化表达式不应是左值。
除了 last 之外的所有情况(即,从初始化表达式创建和初始化临时), 引用被称为直接绑定到初始化表达式。
“最后一个案例”是什么意思? 5.2.2(包括5.2.2.1和5.2.2.2)或5.2.2.2(只有一个)?
换句话说,是5.2.2.1直接绑定吗?
//case 5.2.1.2
struct X{};
struct Y{Y(X);};
const Y& y = X(); // bind directly
struct Z{operator X();};
const X& x = Z(); // bind directly
//case 5.2.2.1
struct A{operator int();};
const int& a = A(); // bind directly or not?
struct B{B(int);};
const B& b = 1; // bind directly or not?
答案 0 :(得分:0)
“最后一个案例”是指5.2.2.2:
- 否则,将从初始化表达式创建临时类型
“cv1 T1”
并复制初始化(8.5)。然后将引用绑定到临时。
这种情况取决于先前的条件是假的,即5.2.2.1:
- 如果
T1
或T2
是班级类型而且T1
与<{> 1}}不是与参考相关的 ...
您的示例的最后两个片段不是这种情况,因为第一个片段T2
属于班级类型且A
不参考相关的int
。在第二个示例中,A
属于类类型,B
与B
无参考相关。由于这些是假的,5.2.2.2不适用(他们做直接绑定)。