4

This question gives a good answer why to define operator overloads as non-members: Operator overloading : member function vs. non-member function?

If you define your operator overloaded function as member function, then compiler translates expressions like s1 + s2 into s1.operator+(s2). That means, the operator overloaded member function gets invoked on the first operand. That is how member functions work!

But what if the first operand is not a class? There's a major problem if we want to overload an operator where the first operand is not a class type, rather say double. So you cannot write like this 10.0 + s2. However, you can write operator overloaded member function for expressions like s1 + 10.0.

Now I have a situation where I need to overload operator==. In my case, only (a) objects of (b) the same type will be compared.

Is there a reason to still define operator== as a non-member or should I implement it as a member in that case?

Community
  • 1
  • 1
Michael
  • 7,407
  • 8
  • 41
  • 84
  • 1
    As far as you know, only objects of the same type will be compared *today*. You don't know the future. Good style is good style. – Richard Hodges May 02 '15 at 08:19

1 Answers1

3

Because operator== has symmetric semantics for its LHS and RHS argument, the recommended approach is to always implement it as a non-member in terms of the public interface of its operands (or if private data is required, to declare it as a friend inside the class).

So

class Bla
{
public:
    // complete interface to data required for comparison
    auto first();
    auto second();
    // ... more
private:
    // data goes here
};

bool operator==(Bla const& L, Bla const& R)
{
    return 
        std::forward_as_tuple(L.first(), L.second() /*, ... */) == 
        std::forward_as_tuple(R.first(), R.second() /*, ... */)
    ;
}

This way, implicit conversion to Bla are considered for both the L and R arguments (I'm not saying implicit conversions are a good idea, but if you have those, it's better to avoid surprises where they are only considered for the RHS argument).

TemplateRex
  • 69,038
  • 19
  • 164
  • 304