конструктор для класса функтора, который может принимать любые вызываемые объекты - PullRequest
0 голосов
/ 22 марта 2020

Я хочу создать класс функторов, который может принимать другие вызываемые объекты. Например, я попробовал следующее:

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

Как создать универсальный c класс Functor, который может принимать любые вызываемые объекты (класс с оператором () или обычная функция) со следующим допустимым синтаксисом.

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

1 Ответ

2 голосов
/ 22 марта 2020

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

Демо

...