用户定义转换的第二个标准转换序列

时间:2014-11-16 05:53:27

标签: c++ c++11 language-lawyer implicit-conversion overload-resolution

我对标准转换序列术语有误解。我看到了以下引用N3797§8.5.3/ 5 [dcl.init.ref]:

  

- 如果是初始化表达式

     
    

- 是xvalue(但不是位字段),类prvalue,数组prvalue或     函数左值和“ cv1 T1”与“ cv2 引用兼容     T2“,或

         

- 具有类类型(即T2是类类型),其中T1不是     与T2相关的引用,可以转换为xvalue类     prvalue,或类型为“ cv3 T3”的函数左值,其中“ cv1 T1”为     参考兼容“ cv3 T3”(见13.3.1.6),

  
     

[..]   在第二种情况下,如果引用是右值引用,则是用户定义转换的第二个标准转换序列   序列包括左值到右值的转换,程序是   不良形成。

这里的第二个标准转换序列是什么?我认为有一个标准的转换序列,包括所有必要的标准转换(用户定义和隐式)。

1 个答案:

答案 0 :(得分:3)

[over.ics.user]:

  

用户定义的转化包含初始标准转化序列,后跟用户定义的转化(12.3),然后是第二个标准转换序列。 [...]
  第二个标准转换序列转换结果   用户定义的转换为序列的目标类型。

E.g。为了

struct A
{
    operator int();
};

void foo(short);

foo(A());

第二个标准转换序列将int prvalue转换为foo的参数,即short。第一个标准转换序列将A对象转换为Aoperator int的隐式对象参数),这构成了身份转换。
对于引用,您引用的规则提供了一个例子:

struct X {
    operator B();
    operator int&();
} x;

int&& rri2 = X(); // error: lvalue-to-rvalue conversion applied to
                  // the result of operator int&

此处,operator int&由重载决策选择。返回值是int的左值引用。为了初始化引用,需要进行左值到右值的转换,这正是引号所阻止的:Lvalues不应该绑定到右值引用。