检测函数对象(函子)和lambda特征

Detecting function object (functor) and lambda traits

本文关键字:lambda 特征 函子 函数 对象 检测      更新时间:2023-10-16

如何检测null和一元函数指针、std::函数对象和函数(包括lambdas)的返回类型和参数类型?

Boost的功能特征和功能特征并不能让我开箱即用,但我愿意补充或取代它们。

我可以这样做:

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

但是我应该如何专门处理函子/lambdas呢?

更新:也许这是对另一个问题的回答,但从重载转换为专业化?

在函子的一般情况下,即使用operator()的类类型中,这是不可能的。这也包括lambda对象。考虑operator()过载的情况:

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)要求类中存在result_type,并假设所有重载在接受不同类型时都返回与该result_type兼容的类型。

当然,给定一些类型T0 ... Tnstd::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;
};

functor_traits<not_overloaded>::type的类型为double (not_overloaded::*)(double) const,只需付出一点努力,您就可以从中提取您想要的内容。(例如,形式Ret (T::*)(Args...) const的专门化将与该类型相匹配。)

[1] :但函子也可以通过隐式转换为函数指针/引用来提供功能,因此您可能会错过

std::result_of出了什么问题?

http://en.wikipedia.org/wiki/C%2B%2B0x#Uniform_method_for_computing_the_return_type_of_function_objects