Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class conversion operator is not called implicitly

In the program below, class A has a convert-to-int operator. Class B has a convert-to-A operator. While the compiler converts A to int implicitly, it fails to do so for converting B to A:

class A
{
protected:
    int _a{0};
public:
    A(int a) : _a(a) {}
    operator int() const {return _a;}
    A operator-(const A& rhs) const {return _a - rhs._a;}
};

class B
{
protected:
    int _b{0};
public:
    B(int b) : _b(b) {}
    operator A() const {return _b;}
};

int main()
{
    A a(1);
    B b(2);
    auto x = 2 - a;  // Ok
    auto y = b - a;  // error: no match for ‘operator-’ (operand types are ‘B’ and ‘A’)
    return 0;
}

Why does it behave like this?

like image 539
modjtabaf Avatar asked Nov 23 '25 13:11

modjtabaf


1 Answers

User-defined conversions on the implicit object parameter of a function are explicitly not allowed in overload resolution.

Because your operator- is defined as member of the class, the left-hand side of - is the implicit object parameter. No attempt will be made to use a user-defined conversion on the argument/operand provided for it, your conversion function from B to A being such a user-defined conversion.

For what it is worth, the built-in - is considered in overload resolution as if there were free operator- overloads taking corresponding built-in types as parameter, which is why there user-defined conversions are permitted on both sides of - and the built-in operator-(int, int) overload is viable for 2 - a.

If you implement your operator- as a free function outside the class, it will work as you expect.

like image 155
user17732522 Avatar answered Nov 25 '25 02:11

user17732522