简体   繁体   English

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

[英]How can I acquire the basic function type from an std::function?

I have a lot of classes with a typedef of std::function<void(PARAMS)> where PARAMS is specific to each class. 我有很多带有std::function<void(PARAMS)>的typedef的类,其中PARAMS特定于每个类。 I need to specialize based on the number of parameters and the first parameter's type. 我需要根据参数的数量和第一个参数的类型进行专门化。 I'd like to use boost::function_traits for this, but in order to use it, I need to have the raw function type of the std::function in question. 我想为此使用boost::function_traits ,但为了使用它,我需要有问题的std::function的原始函数类型。

For example, given std::function<void(int,int)> , I want to retrieve void(int,int) . 例如,给定std::function<void(int,int)> ,我想检索void(int,int)

Is there any way to extract the native type in a portable manner? 有没有办法以可移植的方式提取本机类型? As a side note, I do not have access to C++11 features. 作为旁注,我无法访问C ++ 11功能。

To get the function type, you can use partial specialization: 要获取函数类型,可以使用部分特化:

template <typename T>
struct Detect;

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

Now when you get an unknown std::function<?> type T , you just use 现在当你得到一个未知的std::function<?>类型T ,你就可以使用了

typename Detect<T>::Result

(you might want do define Result as F * , as some contexts (eg, field types) only allow pointer-to-function, and not bare function types. (您可能希望将Result定义为F * ,因为某些上下文(例如,字段类型)仅允许指向函数的指针,而不允许使用裸函数类型。

Edit: 编辑:

To specialize on the number of arguments and the type of the first one, you would need either C++11 variadic templates 要专注于参数的数量和第一个参数的类型,您需要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;
};

or to code the equivalent of the above, using a separate specialization for each possible number of arguments: 或编写上述等价物,为每个可能数量的参数使用单独的专门化:

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 };
  ...
};

...

std::function contains result_type , argument_type for unary functions, and first_argument_type and second_argument_type for binary functions. std::function包含一元函数的result_typeargument_type ,二元函数的first_argument_typesecond_argument_type You can extract these. 你可以提取这些。 For n-ary functions defined with variadic templates, I don't think there is a std::tuple containing all the arguments. 对于使用可变参数模板定义的n-ary函数,我认为没有包含所有参数的std::tuple

If you want your own traits class: 如果你想要自己的特质类:

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;
};

It should be simple enough to create a metafunction to extract the T in the boost::function<T> 它应该是足够简单创建一个元函数来提取Tboost::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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM