"bind directly"在引用初始化中是什么意思?

What does "bind directly" mean in reference initialization?

本文关键字:是什么 意思 引用 bind directly 初始化      更新时间:2023-10-16

N4527 8.5.3 [dcl.init.ref]

5 对类型"cv1

T1"的引用由类型为"cv2 T2"的表达式初始化,如下所示:

(5.1( — [...]

  • (5.1.1( — [...]

  • (5.1.2( — [...]

(5.2( — 否则,引用应为非易失性常量类型的左值引用(即 cv1 应为康斯特(,或引用应为右值引用。

  • (5.2.1( — 如果初始值设定项表达式

    • (5.2.1.1( — 是 x值(但不是位字段(、类 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 无关,则用户定义的转换使用用户定义的类型为"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相同,或高于CV2;和
    • (5.2.2.4( — 如果引用是右值引用,则初始值设定项表达式不应是左值。

除最后一种情况(即从初始值设定项表达式创建和初始化临时(之外的所有情况下,据说引用直接绑定到初始值设定项表达式。

"最后一种情况"是什么意思? 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?

"最后一种情况"指的是 5.2.2.2:

— 否则,将从初始值设定项表达式创建并复制初始化 “cv1 T1” 类型的临时 (8.5(。然后将引用绑定到临时引用。

这种情况取决于前面的条件为 false,即 5.2.2.1:

— 如果T1T2是类类型,并且T1T2引用无关......

示例的最后两个片段并非如此,因为在第一个片段中,A是类类型,intA无关。在第二个示例中,B 属于类类型,Bint引用无关。由于这些是错误的,因此5.2.2.2不适用(它们确实直接绑定(。