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) とその理由です。
与えられたアプローチに矛盾はありますか? はいの場合はお知らせください。
PS:仮定sizeof(char)!= sizeof(long)