我试图检查一个类是否有方法operator==
。我找到了SFINAE here的解决方案,并且它与我制作的课程一起正常工作。
看起来像这样:
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。这是为什么?
答案 0 :(得分:19)
int
不是班级类型且没有会员operator==
,这是您使用&C::operator==
检查的内容。因此,测试产生&#34; no&#34; 。正如其他人正确指出的那样,对于只有非成员operator==
的班级,您的考试也会为负。
如何正确检查operator==
是否存在此处:
How to check whether operator== exists?
答案 1 :(得分:10)
至少有两个基本原因,你的直接方法存在缺陷(或不完整)。
首先,您的方法会检查 class C
是否有名为operator ==
的成员。非类型类型不会通过此测试,因为它们没有任何成员。 int
是非类型。
其次,这种方法本身并不会检测operator ==
作为独立函数实现的类。例如,您的测试会说std::string
没有==
运算符。确实std::string
没有这样的成员,但您可以使用独立std::string
来比较operator ==
的相等性。因此,即使int
不知何故是类类型,它仍然不意味着它将operator ==
实现为成员函数。
答案 2 :(得分:4)
您的测试不会测试表达式C==C
是否有效。它会测试您的班级C
是否有C::operator==
。由于int
不是类,因此没有类成员。
尝试测试,例如typeof(C()==C())
答案 3 :(得分:0)
如果你使用c ++ 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
}