"bind directly" 在引用初始化中是什么意思?
What does "bind directly" mean in reference initialization?
N4527 8.5.3 [dcl.init.ref]
5 A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:
(5.1) — [...]
(5.1.1) — [...]
(5.1.2) — [...]
(5.2) — 否则,引用应为对非易失性常量类型的左值引用(即,cv1 应为
const),或者引用应该是一个右值引用。
(5.2.1) — If the initializer expression
(5.2.1.1) — is an xvalue (but not a bit-field), class prvalue, array prvalue or function lvalue and “cv1 T1”
is reference-compatible with “cv2 T2”, or
(5.2.1.2) — has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be
converted to an xvalue, class prvalue, or function lvalue of type “cv3 T3”, where “cv1 T1” is
reference-compatible with “cv3 T3” (see 13.3.1.6),
then the reference is bound to the value of the initializer expression in the first case and to
the result of the conversion in the second case (or, in either case, to an appropriate base class
subobject).
(5.2.2) — 否则:
(5.2.2.1) — If T1 or T2 is a class type and T1 is not reference-related to T2, user-defined conversions
are considered using the rules for copy-initialization of an object of type “cv1 T1” by userdefined
conversion (8.5, 13.3.1.4, 13.3.1.5); the program is ill-formed if the corresponding non-reference copy-initialization would be ill-formed. The result of the call to the conversion
function, as described for the non-reference copy-initialization, is then used to direct-initialize
the reference. For this direct-initialization, user-defined conversions are not considered.
(5.2.2.2) — Otherwise, a temporary of type “cv1 T1” is created and copy-initialized (8.5) from the initializer
expression. The reference is then bound to the temporary.
If T1 is reference-related to T2:
(5.2.2.3) — cv1 shall be the same cv-qualification as, or greater cv-qualification than, cv2 ; and
(5.2.2.4) — if the reference is an rvalue reference, the initializer expression shall not be an lvalue.
在除 last 之外的所有情况下(即从初始化表达式创建和初始化临时对象),
据说引用直接绑定到初始化表达式。
"last case" 是什么意思? 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?
"last case"指的是5.2.2.2:
— Otherwise, a temporary of type “cv1 T1”
is created and copy-initialized (8.5) from the initializer expression. The reference is then bound to the temporary.
这种情况取决于之前的条件为假,即 5.2.2.1:
— If T1
or T2
is a class type and T1
is not reference-related to T2
...
示例的最后两个片段不是这种情况,因为在第一个片段中 A
是 class 类型而 int
不是 与 A
相关的参考。在第二个例子中,B
是 class 类型并且 B
与 int
没有引用相关。由于这些都是错误的,因此 5.2.2.2 不适用(它们 do 直接绑定)。
N4527 8.5.3 [dcl.init.ref]
5 A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:
(5.1) — [...]
(5.1.1) — [...]
(5.1.2) — [...]
(5.2) — 否则,引用应为对非易失性常量类型的左值引用(即,cv1 应为 const),或者引用应该是一个右值引用。
(5.2.1) — If the initializer expression
(5.2.1.1) — is an xvalue (but not a bit-field), class prvalue, array prvalue or function lvalue and “cv1 T1” is reference-compatible with “cv2 T2”, or
(5.2.1.2) — has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be converted to an xvalue, class prvalue, or function lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3” (see 13.3.1.6),
then the reference is bound to the value of the initializer expression in the first case and to the result of the conversion in the second case (or, in either case, to an appropriate base class subobject).
(5.2.2) — 否则:
(5.2.2.1) — If T1 or T2 is a class type and T1 is not reference-related to T2, user-defined conversions are considered using the rules for copy-initialization of an object of type “cv1 T1” by userdefined conversion (8.5, 13.3.1.4, 13.3.1.5); the program is ill-formed if the corresponding non-reference copy-initialization would be ill-formed. The result of the call to the conversion function, as described for the non-reference copy-initialization, is then used to direct-initialize the reference. For this direct-initialization, user-defined conversions are not considered.
(5.2.2.2) — Otherwise, a temporary of type “cv1 T1” is created and copy-initialized (8.5) from the initializer expression. The reference is then bound to the temporary.
If T1 is reference-related to T2:
(5.2.2.3) — cv1 shall be the same cv-qualification as, or greater cv-qualification than, cv2 ; and
(5.2.2.4) — if the reference is an rvalue reference, the initializer expression shall not be an lvalue.
在除 last 之外的所有情况下(即从初始化表达式创建和初始化临时对象), 据说引用直接绑定到初始化表达式。
"last case" 是什么意思? 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?
"last case"指的是5.2.2.2:
— Otherwise, a temporary of type
“cv1 T1”
is created and copy-initialized (8.5) from the initializer expression. The reference is then bound to the temporary.
这种情况取决于之前的条件为假,即 5.2.2.1:
— If
T1
orT2
is a class type andT1
is not reference-related toT2
...
示例的最后两个片段不是这种情况,因为在第一个片段中 A
是 class 类型而 int
不是 与 A
相关的参考。在第二个例子中,B
是 class 类型并且 B
与 int
没有引用相关。由于这些都是错误的,因此 5.2.2.2 不适用(它们 do 直接绑定)。