No class subtraction operator overloaded but still works

Viewed 143

I have this piece of code:

#include <iostream>
using namespace std;

template <typename T1, typename T2>
class Number {
    T1 value;
public:
    Number(const T1& val): value(val){};
    operator T2() { return (T2)(value / 2); }
    T1 operator+(const T1& val) { return value + val; }
};

int main() {
    Number<int, float>n1(10);
    Number<float, int>n2(3.0);
    cout << n1 + n2 << ", " << n2 + n1 << ", " << n1 - n2 << endl;
}

In spite having no subtraction operator overloaded this code still works and outputs: 11, 8, 4.

Shouldn't it throw an error at compile time ?

Any idea will be appreciated.

2 Answers

When the compiler sees n1 - n2, it performs an overload resolution. For any pair of promoted arithmetic types L and R, the following signatures participate in overload resolution:

LR operator-(L, R)

where LR is the result of usual arithmetic conversions on L and R. (See cppreference) No other signature that participates in overload resolution is relevant.

Therefore, n1 is converted to 5.0f with the help of operator T2(), and n2 is similarly converted to 1. And 5.0f - 1 is 4.0f.

n2 has conversion to int defined, n1 has conversion to float defined, int can be automatically promoted to float. I would expect the expression n1-n2 to be of type float.

Note that the compiler wouldn't perform more than one user-defined conversion on an argument.

Related