Подтвердить что ты не робот

Int имеет оператор ==

Я пытаюсь проверить, имеет ли класс метод operator==. Я нашел решение с SFINAE здесь, и он отлично работает с классом, который я делаю.

Он выглядит следующим образом:

template <typename T>
class comparable
{
    typedef char one;
    typedef long two;

    template <typename C> static one test( typeof(&C::operator==) ) ;
    template <typename C> static two test(...);


public:
    enum { value = sizeof(test<T>(0)) == sizeof(char) };
};

Но когда я пытаюсь:

std::cout << comparable<int>::value << std::endl;

Затем он возвращает false, пока я ожидал, что он вернет true. Почему это?

4b9b3361

Ответ 1

int не является типом класса и не имеет члена operator==, что вы проверяете с помощью &C::operator==. Таким образом, тест дает "нет". Как правильно указали другие, ваш тест также будет отрицательным для классов с только нечленом operator==.

Как правильно проверить, существует ли operator== здесь: Как проверить, существует ли оператор ==

Ответ 2

Ваш немедленный подход является ошибочным (или неполным) по крайней мере по двум основным причинам.

Во-первых, ваш метод проверяет, имеет ли класс C член с именем operator ==. Неклассовые типы не пройдут этот тест, так как у них нет членов. И int является неклассовым типом.

Во-вторых, этот подход сам по себе не определяет классы, для которых operator == реализуется как автономная функция. Например, ваш тест скажет, что std::string не имеет оператора ==. Верно, что std::string не имеет такого члена, но вы можете сравнить std::string на равенство, используя автономный operator ==. Таким образом, даже если int каким-то образом был классом, он все равно не означает, что он будет реализовывать operator == как функцию-член.

Ответ 3

Ваш тест не проверяет правильность выражения C==C. Он проверяет, имеет ли класс C C::operator==. Поскольку int не является классом, у него нет членов класса.

Попробовать тестирование, например. typeof(C()==C())

Ответ 4

Если вы используете С++ 11, вы можете использовать decltype, который сделает реализацию намного проще:

#include <iostream>
#include <type_traits>

using namespace std;

template <class T, class Sfinae = void>
class comparable {
public:
   static constexpr bool value = false;
};

template <class T>
class comparable <T, typename enable_if<is_same<decltype(declval<T>() == declval<T>()), bool>::value>::type> {
public:
   static constexpr bool value = true;
};

class A {
public:
   bool operator==(const A &) {
      return true;
   }
};

class B {
};

int main() {
   cout << comparable<int>::value << endl; // output: 1
   cout << comparable<A>::value << endl; // output: 1
   cout << comparable<B>::value << endl; // output: 0
}