Steven Robbins wrote:
It breaks the idea that "==" is an equivalence relation, which seems to me to unnecessarily complicate things for the user.
Heterogeneous comparisons aren't equivalence relations. Values of different types can't be equivalent. But the question "who decides the meaning of x == y" doesn't have anything to do with equivalence anyway. You have to have an answer to it. The principled approach to heterogeneous comparisons is to define x == y as C(x) == C(y), where C is the common type of X and Y, i.e. a type that can represent all values of X and all values of Y. But this (a) only shifts the question to "who decides C" and (b) doesn't at all work for any op== that doesn't follow the principled approach, such as boost::function::operator== (which considers x == y true when the boost::function x contains y, but for which x == x doesn't compile), or bind(f, _1) == v, which constructs a lambda expression that returns f(x) == v. (Or for _1 == v when using Lambda/Lambda2, for that matter.) 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.