#include <iostream>
struct Data{};
struct Test{
Test() = default;
Test(Data){}
};
int main(){
Data d;
Test const& rf = d;
}
考虑以上 code , 标准说:
Otherwise:
- 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 user-defined conversion ([dcl.init], [over.match.copy], [over.match.conv]); 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, the initializer expression is implicitly converted to a prvalue of type “cv1 T1”. The temporary materialization conversion is applied and the reference is bound to the result.
那么,上面的案例符合哪一条?初始化表达式通过转换构造函数Test::Test(Data)
而不是转换函数
转换为类型Test
。但是请注意 5.2.2.1
中强调的部分,它表示调用转换函数 的结果然后用于直接初始化引用。在我的示例中,被调用函数正在转换构造函数,因此,结果是转换构造函数的结果。
问题 1:
哪个项目符号涵盖了我的示例? 5.2.2.1
还是 5.2.2.2
?
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 rvalue or function lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3” (see [over.match.ref]),
考虑子弹5.2.1.2
,它已经涵盖了类型T2
是类类型的情况,它可以转换为cv3 T3
通过转换函数
。
问题 2:
那么,5.2.2.1
涵盖T2
是类类型,可以通过转换函数
转换为目标类型,是不是多余>, 这样的情况在5.2.1.2
中已经涵盖了吗?
最佳答案
问题 1
[dcl.init.ref]/5.2.2.1 适用于此。它是涵盖用户定义的转换的段落。可接受的转换机制之一是 16.3.1.4 [over.match.copy],它可以在 T1
上使用转换构造函数。使用此构造函数转换值,并将生成的临时值绑定(bind)到引用。
[dcl.init.ref]/5.2.2.2 适用于隐式转换的情况不包括用户定义的转换,例如扩大数字转换。
第 2 期
来自 [dcl.init.ref]:
(5.2.1) If the initializer expression
...
(5.2.1.2) has a class type (i.e.,
T2
is a class type), whereT1
is not reference-related toT2
, and can be converted to an rvalue or function lvalue of type “cv3T3
”, where “cv1T1
” is reference-compatible with “cv3T3
” (see 16.3.1.6),
跳转到 16.3.1.6 [over.match.ref],这里有很多散文,但这是唯一相关的部分:
(1) ... Assuming that “reference to cv1
T
” is the type of the reference being initialized, and “cvS
” is the type of the initializer expression, withS
a class type, the candidate functions are selected as follows:(1.1) The conversion functions of
S
and its base classes are considered. ...
本节的其余部分详细说明了 S
的哪些转换函数可以使用,但这对于示例代码中的情况并不重要。 [over.match.ref] 只考虑用于初始化引用的值类型的转换运算符,这里不是这种情况——Data
没有隐式转换运算符。本节未提及转换 T
的构造函数。
因此 [over.match.ref] 和扩展名 [dcl.init.ref]/5.2.1.2 不适用于这种情况。
关于c++ - 关于引用类型复制初始化的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63460804/