NeoLiu
NeoLiu

Reputation: 232

Is there a way test a type has "bool operator==(const type&, const type&)" in the compiling time?

I write a class to test "type == type" but failed when type has no operator==;

template <typename _Type>
double _test(...){
    return 0;
}

template <typename _Type>
auto _test(_Type&& t)->decltype(t == t){
    return 0;
}

template <typename _Type>
struct has_equal_to
{
    static const bool value = sizeof(_test(std::declval<_Type>())) == sizeof(char);
};

struct test{};

int main()
{
    std::cout << has_equal_to<test>::value << std::endl; // compile failed ~~~~
    return 1;
}

has anyone can help ? Or it is impossible to write a class like this .....

Upvotes: 2

Views: 175

Answers (1)

TartanLlama
TartanLlama

Reputation: 65610

Your first test overload shouldn't be a template, as _Type can't be deduced and doesn't matter in that context anyway:

double _test(...){
    return 0;
}

Live Demo


You can achieve the same thing with a bit less boilerplate using C++17's std::void_t (which you can implement yourself easily for C++11):

template <typename T, typename = void>
struct has_equal_to : std::false_type{};

template <typename T>
struct has_equal_to<T, 
         std::void_t<decltype(std::declval<T>() == std::declval<T>())>>
: std::true_type{};

Live Demo


Or you could use std::experimental::is_detected for even less:

template <typename T>
using equal_to_t = decltype(std::declval<T>() == std::declval<T>());

template <typename T>
using has_equal_to = std::experimental::is_detected<equal_to_t, T>;

Live Demo


On an unrelated note, you shouldn't use names that begin with underscores; they're reserved to the implementation.

Upvotes: 7

Related Questions