template <typename T>
concept HasEq = requires(T t) {
{ t == t } -> std::convertible_to<bool>;
};
struct X {};
static_assert(not HasEq<X>);
//bool a = pair<X, X>{} == pair<X, X>{};
static_assert(! HasEq<pair<X, X>>); // fails! SIGH
I suppose it’s simple enough to define a concept for 'T has support for =='. And it’s simple enough to define a type 'X' which doesn't support the operator==. And the concept seems to work fine for that.
But it is confusing that pair<X,X> doesn't really support operator== (since it delegates to the X operator== that doesn’t exist).
And yet HasEq<pair<X, X>> returns the wrong answer (it says operator== is defined).
This appears to be a bug with the std C++ definitions of operator==(pair,pair), defining operator== unconditionally, instead of using 'enable_if' or 'requires' on the operator== definition. But I'm not really sure what I can do about that to make HasEq work properly (so it would start with understanding if this is really a defect in the std::pair operator== definition).
std::pair
to do the right thing. – Grazstd::pair<T1, T2>::operator==
is indeed not SFINAE friendly. – Euelloperator <=>
is fine BTW. – Euellstatic_assert( !HasEq<std::tuple<X, X>>);
works. – Missilestd::pair::operator==
requires. The change required to make it behave the way you want it to would be to modify the standard to make this SFINAE-friendly (e.g. via a LWG issue). – Spoof