检测函数对象(函子)和lambda traits [英] Detecting function object (functor) and lambda traits
问题描述
如何检测null和一元函数指针,std :: function对象和functor(包括lambdas)的返回类型和参数类型?
How can I detect the return type and parameter types of nullary and unary function pointers, std::function objects, and functors (including lambdas)?
Boost的< a href =http://www.boost.org/doc/libs/1_46_1/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html =nofollow> function_traits 和功能性特质不太适合我,但我可以补充或替换它们。
Boost's function_traits and functional traits don't quite get me there out of the box, but I'm open to supplementing or replacing them.
我可以这样做:
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 );
};
但是我应该怎么专业为functor / lambdas?
But how should I specialize for functors/lambdas?
Update: Perhaps something like in this answer to a different question, but translated from overloading to specialization?
推荐答案
这是不可能的函数的一般情况,即使用 operator()
的类类型。这也包括lambda对象。考虑 operator()
重载的情况:
It's not possible in the general case for functors, i.e. class types using operator()
. This includes lambda objects, too. Consider a case where operator()
is overloaded:
struct functor {
double
operator()(double) const;
int
operator()(int) const;
};
typedef function_traits<functor>::result_type result_type;
result_type
应该是什么?
注意,作为一种解决方法,一些协议(例如Boost.Variant的 boost :: apply_visitor
)要求< c $ c> result_type 出现在类中,假设所有重载,虽然接受不同的类型,都返回一个与 result_type
。
Note that, as a workaround, some protocols (e.g. boost::apply_visitor
from Boost.Variant) require that a result_type
be present in the class, with the assumption that all overloads, while accepting different types, all return a type compatible with this result_type
.
当然给定一些类型 T0 ... Tn
, std: :result_of< functor(T0,...,Tn)> :: type
给出与参数类型相关联的返回类型。
And of course given some types T0 ... Tn
, std::result_of<functor(T0, ..., Tn)>::type
gives the return type associated to the parameter types.
在存在 operator()
的一个重载[1]的情况下,可以使用 operator()
member并检查。
In the case where exactly one overload of operator()
is present[1], you can take the operator()
member and inspect that.
struct not_overloaded {
double
operator()(double) const;
};
template<typename T>
struct functor_traits {
typedef decltype(&T::operator()) type;
};
functor_traits< not_overloaded> :: type
类型 double(not_overloaded :: *)(double)const
在这里,只需一点努力,你可以从这里提取你想要的。 (例如, Ret(T :: *)(Args ...)const
的特殊化将匹配该类型。)
functor_traits<not_overloaded>::type
has type double (not_overloaded::*)(double) const
here, and with just a bit of effort you can extract from this what you want. (e.g. a specialization of the form Ret (T::*)(Args...) const
will match that type.)
[1]:但是函子可以通过隐式转换为函数指针/引用来提供函数,所以你可能错过了
[1]: but a functor can provide functionality by implicitly converting to a function pointer/reference, too, so you could miss that
这篇关于检测函数对象(函子)和lambda traits的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!