【发布时间】:2015-01-25 05:42:14
【问题描述】:
以下程序打印 42:
#include <iostream>
struct A
{
operator int(){ return 42; }
};
struct B
{
operator A(){ return A(); }
};
B b;
int a = A(b);
int main(){ std::cout << a << std::endl; } //42
但是如果我们尝试定义 cope/move 或同时定义这两个构造函数,它就行不通了。
#include <iostream>
struct A
{
A(A&&){ std::cout << "A(A&&)" << std::endl; }
A(A&){ std::cout << "A(A&)" << std::endl; }
operator int(){ return 42; }
};
struct B
{
operator A(){ return A(); }
};
B b;
int a = A(b);
int main(){ std::cout << a << std::endl; } //Error
我想,描述该行为的相关部分是N4296::8.5/17.7 [dcl.init]
如果目标类型是(可能是 cv 限定的)类类型:
[...]
— 否则,如果源类型是(可能是 cv 限定的)类类型,则考虑转换函数。适用的换算 枚举函数(13.3.1.5),并选择最好的一个 通过重载决议(13.3)。用户自定义转换so 调用 selected 以将初始化表达式转换为 正在初始化的对象。如果转换无法完成或正在 模棱两可,初始化格式不正确。
它不应该取决于构造函数的缺席/存在。我们只要有合适的转换函数,就可以选择转换顺序。
【问题讨论】: