我正在尝试实现一种机制来检测提供的类是否包含某些静态方法。这是非常简单的代码,但我无法理解为什么decltype()
无法正常工作EnableIfHasFooMethod
类的专业化:
#include <iostream>
struct A {
static int Foo() { return 0; }
};
template <class T, class = void>
struct EnableIfHasFooMethod {};
template <class T>
struct EnableIfHasFooMethod<T, decltype(T::Foo)> {
typedef void type;
};
template <class T, class = void>
struct HasFooMethod {
static const bool value = false;
};
template <class T>
struct HasFooMethod<T, typename EnableIfHasFooMethod<T>::type> {
static const bool value = true;
};
int main() {
std::cout << HasFooMethod<A>::value << std::endl;
return 0;
}
输出为0
,但应为1
。
答案 0 :(得分:3)
您忘了添加void()
template <class T>
struct EnableIfHasFooMethod<T, decltype(T::Foo, void())> { /* ... */ };
// ...........................................^^^^^^^^
您需要匹配
中的第二种类型(void
)
// ........................vvvv
template <class T, class = void>
struct EnableIfHasFooMethod {};
因此decltype()
必须返回void
iff(当且仅当如此)Foo()
中有T
成员。
你不能写
decltype( T::Foo )
因为在这种情况下,decltype()
会返回不能Foo
的成员void
(如果存在)的类型。
你不能写
decltype( void() )
因为,在这种情况下,decltype()
会返回永远 void
,但如果Foo
中有T
成员,则需要{} / p>
所以解决方案是
decltype( T::Foo , void() )
因此,如果没有Foo
成员,SFINAE可以正常工作,替换失败,如果有void
则返回Foo
。
答案 1 :(得分:0)
因为这可能仍然使人们感兴趣,所以让我指出#include "bmp.c"
int main(){
FILE *BMP_file = fopen("./assets/lenna.bmp", "rb");
struct bmp_header* Header;
memset(&Header, 0, sizeof(struct bmp_header));
Header = read_bmp_header(BMP_file);
printf("%x\n", Header->type);
fclose(BMP_file);
return 0;
}
是多余的(如果我没有记错的话)。这应该同样有效:
EnableIfHasFooMethod