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. Почему это?
Ответы
Ответ 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
}