C ++编译错误:无法从B转换为A,没有构造函数,或者构造函数重载模棱两可

pas*_*cal 7 c++ operator-overloading ambiguity overload-resolution visual-studio-2019

我有一些代码暗示类型转换,尽管有转换方法,但它不会编译...

class A
{
public:
    A(void) :_m(0) { }
    A(int val) : _m(val) {}
private:
    int _m;
};
class B
{
public:
    B(void) : _m(0) {}
    B(int val) : _m(val) {}
    B(const A&);
    // there is a direct conversion operator here
    operator A(void) const { return A(_m); }
    operator int(void) const { return _m; }
private:
    int _m;
};
int main()
{
    B b;
    A a = (A)b; // error C2440 here
}
Run Code Online (Sandbox Code Playgroud)

这是错误消息:

error C2440: 'type cast': cannot convert from 'B' to 'A'
message : No constructor could take the source type, or constructor overload resolution was ambiguous
Run Code Online (Sandbox Code Playgroud)

Vla*_*cow 2

错误信息的意思是这两个操作符

operator A(void) const { return A(_m); }
operator int(void) const { return _m; }
Run Code Online (Sandbox Code Playgroud)

可以用在表达式中

(A)b;
Run Code Online (Sandbox Code Playgroud)

因此,使用这些转换运算符时,可以使用构造函数A( int )或默认的复制构造函数A( const A & )

为了更清楚地重写相应的声明,例如

A a = A( b );
Run Code Online (Sandbox Code Playgroud)

那么是使用第一个转换运算符将对象 b 转换为 A 类型的对象,还是使用第二转换运算符将对象 b 转换为 int 类型的对象。

您可以避免声明运算符的歧义,例如

operator A(void) const & { return A(_m); }
operator int(void) const && { return _m; }
Run Code Online (Sandbox Code Playgroud)

也就是说,对于左值,将使用第一个运算符,而对于右值,将使用第二个运算符。

这是带有修改后的运算符的程序。

#include <iostream>
class A
{
public:
    A(void) :_m(0) { }
    A(int val) : _m(val) {}
private:
    int _m;
};
class B
{
public:
    B(void) : _m(0) {}
    B(int val) : _m(val) {}
    B(const A&);
    // there is a direct conversion operator here
    operator A(void) const & { return A(_m); }
    operator int(void) const && { return _m; }
private:
    int _m;
};

int main()
{
    B b;
    A a = b; 
    A a1 = B();
}
Run Code Online (Sandbox Code Playgroud)