“直接绑定”在引用初始化中意味着什么?

时间:2015-10-11 16:53:02

标签: c++ reference initialization language-lawyer

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?

1 个答案:

答案 0 :(得分:0)

“最后一个案例”是指5.2.2.2:

  

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

这种情况取决于先前的条件是假的,即5.2.2.1:

  

- 如果T1T2是班级类型而且T1与<{> 1}}不是与参考相关的 ...

您的示例的最后两个片段不是这种情况,因为第一个片段T2属于班级类型且A 参考相关的int。在第二个示例中,A属于类类型,BB无参考相关。由于这些是假的,5.2.2.2不适用(他们直接绑定)。