I'm looking for an "is_comparable" typetrait but can't find any.
It's very easy to build one that checks if an operator==
for a class was implemented, but this excludes global defined operators.
Is it impossible to implement a is_comparable typetait?
I take it you mean a trait that, for two types L
and R
and
objects lhs
and rhs
of those types respectively, will yield true
if
the lhs == rhs
will compile and false
otherwise. You appreciate that
in theory lhs == rhs
might compile even though rhs == lhs
, or lhs != rhs
,
does not.
In that case you might implement the trait like:
#include <type_traits>
template<class ...> using void_t = void;
template<typename L, typename R, class = void>
struct is_comparable : std::false_type {};
template<typename L, typename R>
using comparability = decltype(std::declval<L>() == std::declval<R>());
template<typename L, typename R>
struct is_comparable<L,R,void_t<comparability<L,R>>> : std::true_type{};
This applies a popular SFINAE pattern for defining traits that is explained in the answer to this question
Some illustrations:
struct noncomparable{};
struct comparable_right
{
bool operator==(comparable_right const & other) const {
return true;
}
};
struct any_comparable_right
{
template<typename T>
bool operator==(T && other) const {
return false;
}
};
bool operator==(noncomparable const & lhs, int i) {
return true;
}
#include <string>
static_assert(is_comparable<comparable_right,comparable_right>::value,"");
static_assert(!is_comparable<noncomparable,noncomparable>::value,"");
static_assert(!is_comparable<noncomparable,any_comparable_right>::value,"");
static_assert(is_comparable<any_comparable_right,noncomparable>::value,"");
static_assert(is_comparable<noncomparable,int>::value,"");
static_assert(!is_comparable<int,noncomparable>::value,"");
static_assert(is_comparable<char *,std::string>::value,"");
static_assert(!is_comparable<char const *,char>::value,"");
static_assert(is_comparable<double,char>::value,"");
If you want the trait to require that equality is symmetric and that inequality also exists and is symmetric you can see how to elaborate it yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With