Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

has_equal_operator implementation in C++11

I am trying to implement has_equal_operator in C++11 and so far came up with following solution. It works for simple cases like int or struct A{} but fails (returning false positive) for std::vector<A>. Why is it failing and how to fix this?

#include <vector>
#include <iostream>

template<typename T>
constexpr auto has_equal_operator(int) -> decltype(std::declval<T>() == std::declval<T>(), bool()) { return true; }
template<typename T>
constexpr bool has_equal_operator(...) { return false; }

struct A {};

void test()
{
    std::cout << "has_equal_operator<int>: " << has_equal_operator<int>(0) << std::endl;
    std::cout << "has_equal_operator<A>:   " << has_equal_operator< A >(0) << std::endl;
    std::cout << "has_equal_operator<std::vector<A>>:   " << has_equal_operator< std::vector<A> >(0) << std::endl;
}

Output:

has_equal_operator<int>: 1
has_equal_operator<A>:   0
has_equal_operator<std::vector<A>>: 1
like image 784
Yatima Avatar asked May 12 '16 04:05

Yatima


1 Answers

Why does it failing?

std::vector<A> has a non-member operator== function template, which is a match for the == in std::declval<T>() == std::declval<T>() in your code. So the check succeeds.

The fact that the body of that function template won't compile is irrelevant to SFINAE; all that matters is that the declaration is valid.

How to fix this?

The only way I can think of is to manually specialize your trait for standard containers.

like image 91
T.C. Avatar answered Sep 19 '22 11:09

T.C.