类类型直接初始化是否考虑用户定义转换函数?编译矛盾疑问
问题解答
你忽略了直接初始化允许先将初始化器转换为目标类型,再通过目标类型的拷贝/移动构造函数完成初始化的规则,而且这个过程依然符合“仅考虑A的构造函数”的条款要求——因为拷贝/移动构造函数本身就是A的构造函数之一。
具体拆解你的代码执行逻辑:
A a(B{});属于直接初始化,编译器首先会查找A的构造函数,看是否有能直接接受B类型参数的构造函数——显然A没有定义这样的构造函数,这一步没有匹配项。- 接下来,编译器会尝试将初始化器
B{}转换为A类型:由于B定义了operator A()用户定义转换函数,这个转换是合法的,会生成一个临时的A对象(C++17及以后会触发拷贝省略,直接在a的内存空间中构造转换后的对象)。 - 最后,这个临时A对象会作为参数匹配A的拷贝构造函数(或移动构造函数,由编译器自动生成),完成a的初始化。
本质上,整个过程依然是调用A的构造函数(拷贝/移动构造),完全符合条款16.6.2的规定——你之前的误解在于认为“仅考虑A的构造函数”意味着必须直接用B类型作为构造函数参数,但实际上构造函数的参数可以是转换后的目标类型本身,而转换步骤是为了生成这个合法的构造函数参数。
内容的提问来源于stack exchange,提问作者Masquue
相关产品推荐
相关产品推荐

