C++类型萃取编写技巧,废话不多说,上来贴代码最实在,以下代码量有点多,不过这都是在下一手一手敲出来的,小巧好用,把以下代码复制出来,放到相应的hpp文件即可,VS,GCC下均能编译通过
#include<iostream>
#include "../../traits/traits.hpp"
using namespace std;
int show(char i, int j)
{
return 1;
}
struct Stu
{
int show(char i, int j)
{
return 1;
}
};
int main()
{
// 变量;类型萃取
traits::type_traits<int>::const_value_type i = 5; // 通过traits::type_traits可以萃取到int类型的各种"衍生"类型,如指针什么的
// 以下是C函数的相关萃取
traits::function_traits<int(char, int)>::FunctionP_Type func_ptr = show; // 得到指针
func_ptr('a', 4);
cout << traits::function_traits<int(char, int)>::arity << endl; // 萃取出参数个数
cout << typeid(traits::function_traits<int(char, int)>::arg2).name() << endl;//萃取出参数1的类型
cout << typeid(traits::function_traits<int(char, int)>::arg1).name() << endl;//萃取出参数2的类型
// 以下是类成员函数的相关萃取
traits::mfunction_traits<int(Stu::*)(char, int)>::MFunctionP_Type mfunc_ptr = &Stu::show; // 得到指针
Stu stu;
((&stu)->*mfunc_ptr)('a', 4);
cout << typeid(traits::mfunction_traits<int(Stu::*)(char, int)>::arg2).name() << endl;//萃取出参数1的类型
cout << typeid(traits::mfunction_traits<int(Stu::*)(char, int)>::arg1).name() << endl;//萃取出参数2的类型
cout << typeid(traits::mfunction_traits<int(Stu::*)(char, int)>::result_type).name() << endl;//萃取出返回值
cout << typeid(traits::mfunction_traits<int(Stu::*)(char, int)>::class_type).name() << endl;//萃取出类类型
// 以下展示从C函数指针转为类成员函数指针的技巧
traits::fun_to_mem_converter<int(char, int), Stu>::MFunctionP_Type mfunc_ptr2 = mfunc_ptr;
// 以下展示从类成员函数指针转为C函数指针的技巧
traits::mem_to_fun_converter<int(Stu::*)(char, int)>::FunctionP_Type func_ptr2 = func_ptr;
return 0;
}
接下来是traits库的完整代码
########################
// traits.hpp
#ifndef TRAITS_INCLUDE
#define TRAITS_INCLUDE
#include "function_traits.hpp"
#include "mfunction_traits.hpp"
#include "fun_to_mem_converter.hpp"
#include "mem_to_fun_converter.hpp"
#include "type_traits.hpp"
#include "pointer_integer_traits.hpp"
#endif
########################
########################
// traits_config.hpp
#ifndef TRAITS_CONFIG_INCLUDE
#define TRAITS_CONFIG_INCLUDE
#define NAMESPACE_TRAITS_BEGIN namespace traits{
#define NAMESPACE_TRAITS_END }
#endif
########################
########################
//type_traits.hpp
#ifndef TYPE_TRAITS_INCLUDE
#define TYPE_TRAITS_INCLUDE
#include "traits_config.hpp"
NAMESPACE_TRAITS_BEGIN
template<typename T>
struct type_traits
{
typedef T value_type;
typedef const T const_value_type;
typedef T* pointer_type;
typedef const T* const_pointer_type;
typedef T** pointer_pointer_type;
typedef const T** const_pointer_pointer_type;
typedef T& reference_type;
typedef const T& const_reference_type;
typedef T*& pointer_reference_type;
typedef const T*& const_pointer_reference_type;
static bool is_reference(){return false;};
static bool is_pointer(){return false;};
static bool is_value(){return true;};
static bool is_pointer_reference(){return false;}
static bool is_pointer_pointer(){return false;}
static bool is_const_reference(){return false;};
static bool is_const_pointer(){return false;};
static bool is_const_value(){return false;};
static bool is_const_pointer_reference(){return false;}
static bool is_const_pointer_pointer(){return false;}
};
template<typename T>
struct type_traits<const T> : public type_traits<T>
{
static bool is_const_reference(){return false;};
static bool is_const_pointer(){return false;};
static bool is_const_value(){return true;};
static bool is_const_pointer_reference(){return false;}
static bool is_const_pointer_pointer(){return false;}
};