2

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

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

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

4

3 回答 3

10

要获取函数类型,可以使用偏特化:

template <typename T>
struct Detect;

template <typename F>
struct Detect<std::function<F>> {
  typedef F Result;
};

现在,当您获得未知std::function<?>类型T时,只需使用

typename Detect<T>::Result

(您可能希望定义ResultF *,因为某些上下文(例如,字段类型)仅允许指向函数的指针,而不是裸函数类型。

编辑:

要专注于参数的数量和第一个参数的类型,您需要 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 };
  ...
};

...
于 2012-08-21T21:31:22.313 回答
3

std::function包含result_type,argument_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;
};
于 2012-08-21T21:32:47.710 回答
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;
}
于 2012-08-21T21:35:10.883 回答