我写的一个简单的 function traits,功能比 boost::unary_traits 和 boost::binary_traits 强,下面是其实现和一个简单的demo。这个function traits已经被我用在了一个C++ delegate 上,不过做了一些修改,但事实证明这个function_traits很有用。
template <typename Operation>
struct function_traits;
// no argument
// function type
template <typename R>
struct function_traits<R ()>
{
// this is function type, not function pointer type
typedef R (function_type)();
typedef R result_type;
enum{argument_count = 0};
enum{ismemfun = false};
};
// function pointer type
template <typename R>
struct function_traits<R (*)()>
{
typedef R (function_type)();
typedef R result_type;
enum{argument_count = 0};
enum{ismemfun = false};
};
// pointer to member function
template <typename C, typename R>
struct function_traits<R (C::*)()>
{
typedef C class_type;
typedef R result_type;
enum{argument_count = 0};
enum{ismemfun = true};
};
// one argument
template <typename R, typename A>
struct function_traits<R (A)>
{
typedef R (function_type)(A);
typedef R result_type;
enum{argument_count = 1};
typedef A first_argument_type;
};
template <typename R, typename A>
struct function_traits<R (*)(A)>
{
typedef R (function_type)(A);
typedef R result_type;
enum{argument_count = 1};
typedef A first_argument_type;
};
template <typename C, typename R, typename A>
struct function_traits<R (C::*)(A)>
{
typedef C class_type;
typedef R result_type;
enum{argument_count = 1};
enum{ismemfun = true};
typedef A first_argument_type;
};
// two arguments
template <typename R, typename A, typename B>
struct function_traits<R (A, B)>
{
typedef R (function_type)(A);
typedef R result_type;
enum{argument_count = 2};
typedef A first_argument_type;
typedef B second_argument_type;
};
template <typename R, typename A, typename B>
struct function_traits<R (*)(A, B)>
{
typedef R (function_type)(A);
typedef R result_type;
enum{argument_count = 2};
typedef A first_argument_type;
typedef B second_argument_type;
};
template <typename C, typename R, typename A, typename B>
struct function_traits<R (C::*)(A, B)>
{
typedef C class_type;
typedef R result_type;
enum{argument_count = 2};
enum{ismemfun = true};
typedef A first_argument_type;
typedef B second_argument_type;
};
//-----------------------------------------------------------
typedef int (*FUNC0)();
typedef int (*FUNC1)(int);
typedef int (*FUNC2)(int, char);
class AClass{
public:
void speak0();
int speak1(int);
int speak2(int, char);
typedef void (*tspeak0)();
typedef int (*tspeak1)(int);
typedef int (*tspeak2)(int, char);
};
#include <iostream>
#include <typeinfo>
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
cout << typeid(function_traits<int (char)>::result_type).name() << '/n';
cout << typeid(function_traits<int (*)(char)>::result_type).name() << '/n';
cout << typeid(function_traits<int (AClass::*)(int)>::class_type).name() << '/n';
// cout << typeid(function_traits<FUNC2>::first_argument_type).name() << '/n';
// cout << typeid(function_traits<FUNC2>::second_argument_type).name() << '/n';
// cout << typeid(function_traits<int (int ***)>::first_argument_type).name() << '/n';
return 0;
}