Gavin Lambert wrote:
There are tons of existing C++ code that works perfectly well without adhering to principled approaches to defining op==, and breaking this willy-nilly was irresponsible.
I would instead argue that implementing op== in an unprincipled manner was irresponsible in the first place. :)
That's not for you to decide. Some programmer has implemented op==, it's worked for him perfectly well. You are not a party to the transaction. It's traditionally not been C++'s philosophy to dictate the meaning of overloaded operators. There are style guides, sure. These are precisely that, style guides. Defining "unprincipled" operator== overloads is common practice, typically such that x == y means x.something( y ). E.g. struct none {}; class X { private: int id_ = 0; public: explicit X( int id, ... ); bool operator==( int id ) const noexcept { return id_ == id; } bool operator==( none ) const noexcept { return id_ == 0; } }; or the already mentioned boost::function, which uses it to mean "contains". Whatever your definition of equivalence, X is neither equivalent to an int, nor to a 'none', and 'none' doesn't even have operator==.