如何从std :: function获取基本函数类型?

时间:2012-08-21 21:22:17

标签: c++ function tr1 typetraits

我有很多类型为std::function<void(PARAMS)>的类,其中PARAMS特定于每个类。我需要根据参数的数量和第一个参数的类型进行专门化。我想使用boost::function_traits,但为了使用它,我需要使用std::function的原始函数类型。

例如,给定std::function<void(int,int)>,我想要检索void(int,int)

有没有办法以便携方式提取本机类型?作为旁注,我无法访问C ++ 11的功能。

3 个答案:

答案 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_typeargument_type用于一元函数,first_argument_typesecond_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;
}