met*_*tal 8 c++ lambda function-pointers functor function-object
如何检测nullary和unary函数指针,std :: function对象和functor(包括lambdas)的返回类型和参数类型?
Boost的function_traits和功能特性并没有让我开箱即用,但我愿意补充或替换它们.
我可以这样做:
namespace nsDetail
{
class Dummy { Dummy(); };
}
template<class Fn> struct FnTraits;
template<class R>
struct FnTraits<R(*)()>
{
typedef nsDetail::Dummy ParamType;
typedef R ReturnType;
typedef R Signature();
};
template<class R, class P>
struct FnTraits<R(*)(P)>
{
typedef P ParamType;
typedef R ReturnType;
typedef R Signature( P );
};
template<class R>
struct FnTraits< std::function<R()> >
{
typedef nsDetail::Dummy ParamType;
typedef R ReturnType;
typedef R Signature();
};
template<class R, class P>
struct FnTraits< std::function<R(P)> >
{
typedef P ParamType;
typedef R ReturnType;
typedef R Signature( P );
};
Run Code Online (Sandbox Code Playgroud)
但是我应该如何专注于functor/lambdas呢?
更新:或许类似于这个问题的答案,但是从重载转换为专业化?
在一般情况下,对于仿函数,即使用的类类型,这是不可能的operator().这也包括lambda对象.考虑一个operator()重载的情况:
struct functor {
double
operator()(double) const;
int
operator()(int) const;
};
typedef function_traits<functor>::result_type result_type;
Run Code Online (Sandbox Code Playgroud)
应该result_type是什么?
请注意,作为一种变通方法,某些协议(例如boost::apply_visitor来自Boost.Variant)要求result_type在类中存在,假设所有重载在接受不同类型的同时都返回与此类型兼容的类型result_type.
当然,给定一些类型T0 ... Tn,std::result_of<functor(T0, ..., Tn)>::type给出与参数类型相关的返回类型.
如果operator()只存在一个重载[1],您可以带走该operator()成员并进行检查.
struct not_overloaded {
double
operator()(double) const;
};
template<typename T>
struct functor_traits {
typedef decltype(&T::operator()) type;
};
Run Code Online (Sandbox Code Playgroud)
functor_traits<not_overloaded>::typedouble (not_overloaded::*)(double) const这里有类型,只需稍加努力就可以从中提取出你想要的东西.(例如,表单的特化Ret (T::*)(Args...) const将匹配该类型.)
[1]:但是仿函数也可以通过隐式转换为函数指针/引用来提供功能,因此您可能会错过它