LINUX.ORG.RU

История изменений

Исправление asaw, (текущая версия) :

Я упростил решение, пользуясь тем, что указатели на функции известны компилятору и могут быть параметрами шаблонов:

#include <functional>
#include <string>

template <typename F, F>
struct X {};

template <typename Ret, typename Class, typename... Args, Ret(Class::*F)(Args...)>
struct X<Ret(Class::*)(Args...), F> {
    Class* _this;
    Ret (Class::*_f)(Args...);
    X(Class* c) : _this(c), _f(F) {}

    std::function<Ret(Args&&...)> operator() () {
        return [&] (Args&&... args) { (_this->*_f)(std::forward<Args>(args)...); };
    }
};

class A {
public:
    A() : foo_functor_producer(this) {} // никаких make_X() не нужно
    void foo(int arg1, int& arg2, std::string& str) {}

    X<decltype(&A::foo), &A::foo> foo_functor_producer;
};

Исходная версия asaw, :

Я упростил решение, пользуясь тем, что указатели на функции известны компилятору и могут быть параметрами шаблонов:

#include <functional>
#include <string>

template <typename F, F>
struct X {};

template <typename Ret, typename Class, typename... Args, Ret(Class::*F)(Args...)>
struct X<Ret(Class::*)(Args...), F> {
    Class* _this;
    Ret (Class::*_f)(Args...);
    X(Class* c) : _this(c) {}

    std::function<Ret(Args&&...)> operator() () {
        return [&] (Args&&... args) { (_this->*_f)(std::forward<Args>(args)...); };
    }
};

class A {
public:
    A() : foo_functor_producer(this) {} // никаких make_X() не нужно
    void foo(int arg1, int& arg2, std::string& str) {}

    X<decltype(&A::foo), &A::foo> foo_functor_producer;
};