#include <iostream>
struct Data{};
struct Test{
Test() = default;
Test(Data){}
};
int main(){
Data d;
Test const& rf = d;
}
考虑上面的代码,标准说:
否则:
- 5.2.2.1 如果T1 或 T2 是类类型并且 T1 与 T2 没有引用相关,则用户定义的转换被认为是使用通过用户定义的转换来复制初始化类型为“cv1 T1”的对象的规则([ dcl.init]、[over.match.copy]、[over.match.conv]);如果相应的非参考复制初始化格式错误,则程序格式错误。调用转换函数的结果,如针对非引用复制初始化所描述的,然后用于直接初始化引用。对于这种直接初始化,不考虑用户定义的转换。
- 5.2.2.2 否则,初始化表达式被隐式转换为“cv1 T1”类型的纯右值。应用临时实现转换并将引用绑定到结果。
那么,上述案例服从哪个项目符号?初始化表达式Test
通过转换构造函数Test::Test(Data)
而不是conversion function
. 但是请注意 中强调的部分5.2.2.1
,它表示调用转换函数的结果然后用于直接初始化引用。在我的示例中,被调用的函数是转换构造函数,因此,结果是转换构造函数的结果。
问题一:
哪个项目符号涵盖了我的示例?5.2.2.1
还是5.2.2.2
?
5.2.1.2 有一个类类型(即T2是一个类类型),其中T1与T2没有引用相关,可以转换为“cv3 T3”类型的右值或函数左值,其中“cv1 T1”是与“cv3 T3”参考兼容(参见[over.match.ref]),
考虑一下子弹5.2.1.2
,它已经涵盖了类型T2
是类类型的情况,并且可以转换为cv3 T3
through conversion function
。
问题 2:
那么,5.2.2.1
coversT2
是类类型是不是多余,可以通过转换成destination类型呢conversion function
,这样的case已经覆盖了5.2.1.2
?