我有很多类型为std::function<void(PARAMS)>
的类,其中PARAMS特定于每个类。我需要根据参数的数量和第一个参数的类型进行专门化。我想使用boost::function_traits
,但为了使用它,我需要使用std::function
的原始函数类型。
例如,给定std::function<void(int,int)>
,我想要检索void(int,int)
。
有没有办法以便携方式提取本机类型?作为旁注,我无法访问C ++ 11的功能。
答案 0 :(得分:10)
要获取函数类型,可以使用部分特化:
template <typename T>
struct Detect;
template <typename F>
struct Detect<std::function<F>> {
typedef F Result;
};
现在,当您收到未知的std::function<?>
类型T
时,只需使用
typename Detect<T>::Result
(您可能希望将Result
定义为F *
,因为某些上下文(例如,字段类型)仅允许指向函数的指针,而不是裸函数类型。
编辑:
要专注于参数的数量和第一个的类型,您需要C ++ 11可变参数模板
template <typename T>
struct Detect;
template <typename R, typename A, typename... As>
struct Detect<std::function<R(A,As...)>> {
static constexpr auto numargs = 1 + sizeof...(As);
typedef R Result;
typedef A FirstArg;
};
或编写上述等价物,对每个可能数量的参数使用单独的专门化:
template <typename R, typename A1>
struct Detect<std::function<R(A1)>> {
enum { numargs = 1 };
typedef R Result;
typedef A1 FirstArg;
};
template <typename R, typename A1, typename A2>
struct Detect<std::function<R(A1,A2)>> {
enum { numargs = 2 };
...
};
...
答案 1 :(得分:3)
std::function
包含result_type
,argument_type
用于一元函数,first_argument_type
和second_argument_type
用于二元函数。你可以提取这些。对于使用可变参数模板定义的n-ary
函数,我认为不存在包含所有参数的std::tuple
。
如果你想要自己的特质课程:
template<typename Fun>
struct function_traits;
template<typename R, typename... Args>
struct function_traits<std::function<R(Args...)>
{
typedef R return_type;
typedef std::tuple<Args...> arguments_type;
};
答案 2 :(得分:2)
创建一个元函数以提取T
boost::function<T>
应该很简单
template<typename T>
struct func_extractor
template<typename T>
struct func_extractor<boost::function<T> >
{
typedef T type;
};
int main()
{
typedef boost::function<void(int, int)> func_type1;
typedef func_extractor<func_type1>::type extracted_type;
typedef boost::function<extracted_type> func_type2;
std::cout << boost::is_same<func_type1, func_type2>::value << std::endl;
}