先说一个简单的方案. 经过验证 g++ 和 vs2010 都可以.
原理就是利用函数类型可以直接转换成函数指针.
template<class T> bool test( T * t )
{
return true;
}
bool test( ... )
{
return false;
}
#include<iostream>
using namespace std;
int main()
{
int k = 12;
cout << test(main) << endl;
cout << test( k ) << endl;
typedef int(*PtrFun)();
PtrFun ptr = main;
cout << test(ptr) << endl;
cout << test( 12 ) << endl;
return 0;
}
再说一个稍微复杂点的方案. g++ 编译没问题. vs2010 编译不过去.
利用了函数类型没有数组的概念. 入梅不存在某个类型的数组, 0 转换 U (*)[1] 自然会失败
template<class T>
class IsFunction
{
private:
typedef char ONE;
typedef struct{char a[2];} TWO;
template<class U>static ONE test(...);
template<class U>static TWO test(U (*)[1]);
public:
enum{YES = sizeof(IsFunction<T>::test<T>(0)) == 1 };
enum{NO = !YES};
};
template<>
class IsFunction<T&>
{
public:
enum{YES = 0 };
enum{NO = !YES};
}
template<>
class IsFunction<void>
{
public:
enum{YES = 0 };
enum{NO = !YES};
}
template<>
class IsFunction<const void>
{
public:
enum{YES = 0 };
enum{NO = !YES};
}
template<class T>
long kkk(T&){return IsFunction<T>::YES;}
#include<iostream>
using namespace std;
int main()
{
int k = 23;
cout << kkk(main) << endl;
cout << kkk(k) << endl;
cout << IsFunction<int>::YES << endl;
typedef int(*PtrFun)();
PtrFun ptr = main;
cout << IsFunction<PtrFun>::YES << endl;
return 0;
}