
Dave Harris wrote:
In-Reply-To: <012301c5299e$0e2b2f90$6501a8c0@pdimov2> pdimov@mmltd.net (Peter Dimov) wrote (abridged):
We can't prevent these mistakes in general; if you omit a member (that affects the equivalence relation) when computing the hash value, the computation is just wrong.
In this case the computation was correct, and indeed carefully chosen, but produced needlessly many collisions.
We can't tell if it was correct, because you didn't specify the equality function for the type. Consider something along the lines of: template <class X, class Y> bool container_equal(X const& x, Y const& y); bool MyType::operator==(MyType const& x) { return container_equal(use_a ? a : b, x.use_a ? x.a : x.b); } The types of a and b also matters, the static casts here are a little worrying. But the point is, if the types are right, then Peter's proposal is ideal in this situation. And it wasn't actually correct (with the current interface). It called hash_value directly, which you shouldn't do in general. I'm going to change the documentation to stress this more. Daniel