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

5 c++ language-lawyer overload-resolution implicit-conversion c++11

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

— 如果初始化表达式

— 是 xvalue(但不是位域)、类纯右值、数组纯右值或函数左值,并且“ cv1 T1”与“ cv2 T2”引用兼容,或

— 具有类类型(即,T2 是类类型),其中 T1 与 T2 没有引用相关,并且可以转换为“ cv3 T3”类型的 xvalue、类纯右值或函数左值,其中“ cv1 T1” ”与“ cv3 T3”(见13.3.1.6)引用兼容,

[..] 在第二种情况下,如果引用是右值引用并且用户定义的转换序列的第二个标准转换序列包括左值到右值的转换,则程序格式错误。

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

Col*_*mbo 4

[over.ics.user]:

\n\n
\n

用户定义的转换由初始标准转换序列、用户定义的转换(12.3)和第二个标准转换序列组成。[\xe2\x80\xa6]
\n 第二个标准转换序列将用户定义转换的结果\n 转换为序列的目标类型。

\n
\n\n

例如对于

\n\n
struct A\n{\n    operator int();\n};\n\nvoid foo(short);\n\nfoo(A());\n
Run Code Online (Sandbox Code Playgroud)\n\n

第二个标准转换序列将int纯右值转换为 的参数foo,即short。第一个标准转换序列将A对象转换为A( 的隐式对象参数operator int),这构成了恒等转换。
作为参考,您引用的规则提供了一个示例:

\n\n
struct X {\n    operator B();\n    operator int&();\n} x;\n\nint&& rri2 = X(); // error: lvalue-to-rvalue conversion applied to\n                  // the result of operator int&\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里,operator int&是通过重载决策来选择的。返回值是对的左值引用int。为了初始化引用,需要进行左值到右值的转换,而这正是引用所阻止的:左值不应绑定到右值引用。

\n