以下代碼顯示了一個SFINAE實現,用於檢查類型(基本上是一個類)在編譯時是否包含成員函數member_func
。SFINAE方法比較
#define CHECKER(func_name,class_name) sizeof(class_name<T>::template func_name<T>(0)) == 1
#include <iostream>
struct A
{
void member_func();
};
struct B {};
template<typename T>struct Check_If_T_Is_Class_Type
{
template<typename C> static char func (char C::*p);
template<typename C> static long func (...);
enum{val = CHECKER(func,Check_If_T_Is_Class_Type)};
};
//APPROACH 1
template <typename T>struct TypeHasMemberFunc
{
template <typename C, C> struct TypeCheck;
template <typename C> struct Prototype_Holder {typedef void (C::*fptr)();};
template <typename C> static char func(TypeCheck
<
typename Prototype_Holder<C>::fptr,
&C::member_func
>*);
template <typename C> static long func(...);
enum {value = CHECKER(func,TypeHasMemberFunc)};
};
//APPROACH 2
template <typename T>struct has_member_func
{
template<class C> static char func(char (*)[sizeof(&C::member_func)]);
template<class C> static long func(...);
enum{value = CHECKER(func,has_member_func)};
};
int main(){
if(Check_If_T_Is_Class_Type<A>::val)
std::cout<<TypeHasMemberFunc<A>::value; //using APPROACH 1
if(Check_If_T_Is_Class_Type<B>::val)
std::cout<<has_member_func<B>::value; //using APPROACH 2
}
但是我的問題是您更喜歡哪種方法(方法1或方法2),爲什麼?
你發現在給定的方法有任何不一致嗎?如果是,請讓我知道。
P.S:假設sizeof(char)!= sizeof(long)
另請參閱http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence/3627243#3627243。它有一些非常好的答案。 – FireAphis 2011-01-03 17:19:05