微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 检测函数对象(仿函数)和lambda特征

如何检测nullary和unary函数指针,std :: function对象和functor(包括lambdas)的返回类型和参数类型?

Boost的function_traitsfunctional 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 );
};

但是我应该如何专注于functor / lambdas呢?

更新:也许类似于this answer to a different question,但从重载转换为专业化?

解决方法

在一般情况下,对于仿函数,即使用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 … 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;
};

functor_traits< not_overloaded> :: type在这里有类型double(not_overloaded :: *)(double)const,只需稍加努力就可以从中提取出你想要的东西. (例如,Ret(T :: *)(Args …)const形式的特化将匹配该类型.)

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

原文地址:https://www.jb51.cc/c/118981.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐