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

C++ 如何从std::function获取基本函数类型?,c++,function,tr1,typetraits,C++,Function,Tr1,Typetraits,我有很多类的typedef为std::function,其中PARAMS特定于每个类。我需要根据参数的数量和第一个参数的类型进行专门化。我想为此使用boost::function\u traits,但为了使用它,我需要有问题的std::function的原始函数类型 例如,给定std::function,我想检索void(int,int) 有没有办法以可移植的方式提取本机类型?作为补充说明,我没有访问C++11功能的权限。要获取函数类型,可以使用部分专门化: template <typen

我有很多类的typedef为
std::function
,其中PARAMS特定于每个类。我需要根据参数的数量和第一个参数的类型进行专门化。我想为此使用
boost::function\u traits
,但为了使用它,我需要有问题的
std::function
的原始函数类型

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


有没有办法以可移植的方式提取本机类型?作为补充说明,我没有访问C++11功能的权限。

要获取函数类型,可以使用部分专门化:

template <typename T>
struct Detect;

template <typename F>
struct Detect<std::function<F>> {
  typedef F 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;
};
模板
结构检测;
模板
结构检测{
静态constexpr auto numargs=1+sizeof…(As);
打字结果;
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 };
  ...
};

...
模板
结构检测{
枚举{numargs=1};
打字结果;
typedef A1 FirstArg;
};
模板
结构检测{
枚举{numargs=2};
...
};
...

std::function
包含一元函数的
结果类型
参数类型
,以及二进制函数的
第一个参数类型
第二个参数类型
。您可以提取这些。对于使用可变模板定义的
n元
函数,我认为没有
std::tuple>包含所有参数

如果您想要自己的traits类:

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;
};
模板
结构功能特征;
模板

struct function\u traits在
boost::function

模板
结构函数提取器
模板
结构函数提取器
{
T型;
};
int main()
{
typedef boost::函数func_type1;
typedef func_提取器::type extracted_type;
typedef boost::函数func_type2;

std::cout
std::function
在C++11中是新功能,那么您如何不使用它呢?
std::function
是TR1的一部分。我省略了TR1名称空间。如此迂腐对任何人都没有好处。那么请告诉我们哪些C++11功能您没有访问权限,也许您已经有了TR1@dauphic当前位置他不是学究,他只是指点你声称没有C++11可用,但你想对C++11的东西进行推理(如果你使用tr1,那么你肯定会告诉我们你使用的是std::tr1::function,所以这很混乱)。此外,大多数人问问题和说“没有C++11”意味着“只有C++03”@daupic:
std::function
是可变模板,因此当它移动到
std
命名空间时,它将升级为可变模板(前提是您的编译器支持该功能)。您似乎有一个小错误--
函数的非专门化声明有多个参数,而不是一个(您为它提供了
std::function
;这是“偶然”发生的,
Args
始终为空:)仍然错误(现在它甚至无法编译)--只需使用
模板类函数_traits;
;另外,将其设为结构,或在提取的traits之前添加
public:
)@GrzegorzHerman夏季,温度正在煮我的大脑:-)现在快到午夜了,所以温度要好得多:)在部分规范中使用
Args&&
会让事情变得非常糟糕,按值参数变成右值引用。不要这样做。
typedef std::tuple参数类型;static std::size\t const num\u参数=sizeof…(Args);
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;
};
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;
}