以下程序打印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)。用户定义的转换就是这样 调用selected来将初始化表达式转换为 对象被初始化。如果转换无法完成或是 暧昧,初始化是不正确的。
它不应该取决于构造函数的缺失/存在。我们只需要有适当的转换函数,以便选择转换序列。
答案 0 :(得分:1)
您有效删除了默认构造函数。从标准(12.1 / 4,强调我的):
类
X
的默认构造函数是类X
的构造函数,可以在不带参数的情况下调用。 如果 对于类X
没有用户声明的构造函数,隐式声明没有参数的构造函数 默认
IF 没有用户声明的构造函数。但是你声明了两个,所以没有隐式的默认构造函数。因此,这个:
operator A(){ return A(); }
// ^^^
无法编译。这就是你得到的错误
的原因错误:没有匹配函数来调用
A::A()
代码尝试调用您的转换运算符 - 但正文无效。