Keiji
Keiji

Reputation: 1042

Why doesn't C++ implicitly convert the LHS argument to a non-friend operator overload?

Consider the following: (Compiler Explorer link)

class A {
private:
    int val;

public:
    inline A() : val(0) {}
    inline A(int x) : val(x) {}
    //inline bool operator<(const A& other) const {return val < other.val;}
    friend inline bool operator<(const A& lhs, const A& rhs) {return lhs.val < rhs.val;}
};

int main(int, char**) {
    A a;
    //return 2 < a;
    return a < 2;
}

error: no match for 'operator<' (operand types are 'int' and 'A')

Clearly, C++ is capable of performing implicit conversion (from int to const A&) on either side of the < when using the friend version of the operator. I would have expected the non-friend version to work the same, but it seems a value cannot be implicitly converted when it needs to end up as the "this" object in an operator overload.

I suppose if I defined a regular non-operator function instead of an operator, I wouldn't expect (2).func(a) to perform an implicit conversion either, so looking at it this way it makes sense, but it still seems weird that conversion isn't done in the case of an operator.

Does C++ disallow this form of implicit conversion because it considers it like a member function call? Or is there a different reason that's specific to operators? Does the standard make any comment on attempting to use a member operator in this way?

Upvotes: 1

Views: 239

Answers (1)

BoP
BoP

Reputation: 3150

The compiler first selects a set of possible overloads, and then considers if some operands are convertible to the parameter types of any of those overloads.

The compiler does not do all possible convertions to find if any of those have suitable member functions (or operators).

Consider if A had a constructor

template<class T>
A(T);

Now the compiler would have to consider the member bool operator<(const A& other) for any type T. Not what we want.

Upvotes: 0

Related Questions