samedi 20 décembre 2014

Wrapping a non-static method into std::function with "this" parameter bound using as little code as possible

Here's what I'm trying to do:



template <typename ...Arguments>
class CSignal
{
public:
void connect(std::function<void(Arguments...)> target)
{
m_connections.emplace_back(target);
}

private:
mutable std::vector<std::function<void(Arguments...)>> m_connections;
};


And connect works great for static methods or global functions. Now, what if I want to pass a member method? It seems that here is my only option:



struct MyStruct
{
void print(float a, int b)
{
std::cout << a << " " << b << std::endl;
}
} st;

signal.connect(std::bind(&MyStruct::print, &st, std::placeholders::_1, std::placeholders::_2));


It would suit me if I didn't have to specify placeholders which is quite cumbersome. So I try another approach. I add a new connect overload for member methods:



template <class T, typename Method>
void connect(const T* target, Method method)
{
m_connections.emplace_back([=](Arguments... args){target->*method(std::forward<Arguments>(args)...);});
}


And then:



signal.connect(&st, &MyStruct::print);


But now I get a compilation error:



term does not evaluate to a function taking 2 arguments



at



m_connections.emplace_back([=](Arguments... args){target->*method(std::forward<Arguments>(args)...);});


What's the problem here? And is there any way to do this, without declaring second connect overload or using std::bind with placeholders?


P. S. In my second connect overload, the template one, is there a way to specify explicitly that Method is a member method of T in the declaration of Method itself?


Aucun commentaire:

Enregistrer un commentaire