Reputation: 232
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
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;
}
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{};
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>;
On an unrelated note, you shouldn't use names that begin with underscores; they're reserved to the implementation.
Upvotes: 7