类型萃取
借用化学中的萃取概念,类型萃取即将混合类型中的部分类型提取出来。在C++中可以使用模板实现这个功能。
非类成员变量的类型萃取
对于变量混合类型如 int*
、const int
等,我们可以将 *
和 const
去掉,只留下 int
。
template <typename T>
struct remove_pointer;
template <typename T>
struct remove_pointer<T*> {
using type = T;
};
int main() {
using type = remove_pointer<int*>::type; //using type = int
return 0;
}
template <typename T>
struct remove_const;
template <typename T>
struct remove_const<const T> {
using type = T;
};
int main() {
using type = remove_const<const int>::type; //using type = int
return 0;
}
对于上面两段代码,我们先声明了一个类模板,然后将这个类模版进行偏特化,这样就能使得特定的类型匹配这个模板的偏特化,从而将部分类型萃取出来。
非类成员函数的类型萃取
对于一个函数,我们可以使用类型萃取将它的返回值类型,参数类型提取出来。
假设我们有一个函数,它有一个参数
bool Foo(int) {
return true;
}
我们可以用通过函数指针,用类似的的方法萃取函数的返回值类型和参数类型。
template <typename T>
struct function_traits;
template <typename Ret, typename Param>
struct function_traits<Ret (*)(Param)> {
using ret_type = Ret;
using param_type = Param;
};
int main() {
using function_info = function_traits<decltype(&Foo)>;
using ret = function_info::ret_type; //using ret = bool
using param = function_info::param_type; //using param = int
return 0;
}
若函数有不止一个参数,可以使用变长参数模板
bool Foo(int, double, bool) {
return true;
}
template <typename T>
struct function_traits;
template <typename Ret, typename... Args>
struct function_traits<Ret (*)(Args...)> {
using ret_type = Ret;
using param_type = std::tuple<Args...>;
};
int main() {
using function_info = function_traits<decltype(&Foo)>;
using ret = function_info::ret_type; //using ret = bool
using param = function_info::param_type; //using param = std::tuple<int, double, bool>
return 0;
}
类成员类型萃取
对于一个类,带有成员变量和成员函数,由于类的成员的指针的特殊性,我们不能直接用上面的方法进行类型萃取,需要在模板的类型参数中额外记录类的信息。
比如,我们有下面的类
struct Person {
bool IsFemale(int) { return true; };
float height;
};
这个类中既有成员函数 IsFemale
,还有成员变量 height
,我们如何从类中萃取成员的类型信息?
template <typename T>
struct function_traits;
template <typename T>
struct variable_traits;
template <typename Ret, typename Class, typename Param>
struct function_traits<Ret (Class::*)(Param)> {
using ret_type = Ret;
using class_type = Class;
using param_type = Param;
};
template <typename Type, typename Class>
struct variable_traits<Type(Class::*)> {
using type = Type;
using class_type = Class;
};
int main() {
using function_info = function_traits<decltype(&Person::IsFemale)>;
using function_ret = function_info::ret_type; //using function_ret = bool
using function_param = function_info::param_type; //using function_param = int
using variable_info = variable_traits<decltype(&Person::height)>;
using variable_type = variable_info::type; //using variable_type = float
return 0;
}
因为类的成员指针类型为 Class::*
,所以在模板中也要改成相应的格式。
以上就是类型萃取的方法,该方法在构建反射系统中有重要的作用。
标签:function,struct,int,param,类型,using,type,萃取 From: https://www.cnblogs.com/imyhy/p/18383521