【问题标题】:constructor for functor class that can accept any callable objects可以接受任何可调用对象的仿函数类的构造函数
【发布时间】:2020-03-22 08:21:36
【问题描述】:

我想创建一个可以接受其他可调用对象的仿函数类。 例如,我尝试了以下方法:

#include <iostream>
template<class RetType,class ObjType,class... Params>
struct Functor {
    using FuncSig = RetType (ObjType::*)(Params...);
    FuncSig funcptr;
    ObjType *obj;

    RetType operator()(Params... params) {
        return (obj->*funcptr)(params...);
    }
};
class command {
    int x;
    char *ch;
    public:
    void operator()(int a,char *x) {
        // some task
        std::cout << "task1 done!" << std::endl;
    }
};

int main() {
    Functor<void,command,int,char *> f;
    command c;
    f.funcptr = &command::operator();
    f.obj = &c;
    char x[] = {'a','b'};
    f(100,x);
}

这行得通。但是当我想使用普通的函数可调用对象时,我需要创建一个不同的 Functor 类:

#include <iostream>
template<class RetType,class ObjType,class... Params>
struct Functor {
    using FuncSig = RetType (ObjType::*)(Params...);
    FuncSig funcptr;
    ObjType *obj;

    RetType operator()(Params... params) {
        return (obj->*funcptr)(params...);
    }
};
class command {
    int x;
    char *ch;
    public:
    void operator()(int a,char *x) {
        // some task
        std::cout << "task1 done!" << std::endl;
    }
};

template<class RetType,class... Params>
struct Functor2 {
    using FuncSig = RetType (*)(Params...);
    FuncSig funcptr;

    RetType operator()(Params... params) {
        return (*funcptr)(params...);
    }
};
void normalFunction(double x) {
    std::cout << "task2 done!" << std::endl;    
}

int main() {
    Functor<void,command,int,char *> f;
    command c;
    f.funcptr = &command::operator();
    f.obj = &c;
    char x[] = {'a','b'};
    f(100,x);

    //........
    Functor2<void,double> g;
    g.funcptr = normalFunction;
    g(1.2);
}

如何创建一个通用 Functor 类,该类可以接受任何可调用对象(带有 operator() 的类或普通函数),并具有以下可接受的语法。

Functor<ReturnType,int,double,more params ..> F(a_callable_objects);
F(arguments);

【问题讨论】:

  • 使用std::function

标签: c++ c++11 c++14 functor


【解决方案1】:

使用std::function,您可以这样做:

command c;
std::function<void(int, char *)> f = [&](int n, char* buf){ return c(n, buf); };
char x[] = {'a', 'b'};
f(100, x);

//...
std::function<void(double)> g = normalFunction;
g(1.2);

Demo

【讨论】:

  • 嗨 Jarod42,我有一个问题,我正在阅读“现代 C+ 设计”一书。他们深入讨论函子。可以使用 std::function 代替仿函数类吗?
  • std::function 是一个接受函子的函子。当它键入擦除其内容时,它会产生一些额外的成本。它可能具有“更干净”的界面,因为它清楚地说明了与常规模板相反的输入/输出。
猜你喜欢
  • 1970-01-01
  • 2013-08-07
  • 1970-01-01
  • 2016-03-04
  • 2021-05-08
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多