Templating boost :: bind to automatically handle multiple arguments for a member function

I have a class with the Attach function, which takes a function object and stores it in a collection. The class itself is obscured by the signature of the function. Something like that:

template<class Signature>
class Event
{
public:

 void Attach(boost::function<Signature> signature)
 {
  MySignatures.push_back(signature);
 }

private:

 std::list<boost::function<Signature>> MySignatures;
};

To demonstrate usage, consider the following class:


class Listening
{
public:

 int SomeFunction(int x, int y, int z); 
};

To pass the function to Listeningin Event, I will need to write:


 Event<int(int, int, int)> myEvent;
 Listening myListening;

 myEvent.Attach(boost::bind(boost::mem_fn(&Listening::SomeFunction), &myListening, _1, _2, _3));

Therefore, instead of doing this for each case that may be error prone, I write a set of macros as follows:


 #define EventArgument0(x, y)  boost::bind(boost::mem_fn(x), y)
 #define EventArgument1(x, y)  boost::bind(boost::mem_fn(x), y, _1)
 #define EventArgument2(x, y)  boost::bind(boost::mem_fn(x), y, _1, _2)
 #define EventArgument3(x, y)  boost::bind(boost::mem_fn(x), y, _1, _2, _3)
 #define EventArgument4(x, y)  boost::bind(boost::mem_fn(x), y, _1, _2, _3, _4)

 etc.

and then I can write:


 myEvent.Attach(EventArgument3(&Listening::SomeFunction, &myListening));

which is much easier to read (I think). Now to my question: how can I write instead:


 myEvent.Attach(EventArgument(&Listening::SomeFunction, &MyListening));

or even better:


 myEvent.Attach(&Listening::SomeFunction, &myListening);

Attach , <Signature> ( , int(int, int, int))? -, .

.

: , boost::mem_fn, boost::bind , :

bind(&MyClass::Hello, myClass, _1, _2, _3);

:

bind(mem_fn(&MyClass::Hello), myClass, _1, _2, _3);

: &MyClass::Hello _1, _2, _3 .., , Event ?

+3
2

Attach -:

template<typename R,typename T,typename U>
void Attach(R (T::*pmf)(),U* p))
{
    Attach(boost::bind(pmf,p));
}

template<typename R,typename T,typename U,typename A1>
void Attach(R (T::*pmf)(A1),U* p))
{
    Attach(boost::bind(pmf,p,_1));
}

template<typename R,typename T,typename U,typename A1,typename A2>
void Attach(R (T::*pmf)(A1,A2),U* p))
{
    Attach(boost::bind(pmf,p,_1,_2));
}

- const, .

+2

Attach() , . , , .

template<typename A1>
void Attach(A1 a1);

template<typename A1, typename A2>
void Attach(A1 a1, A2 a2);

template<typename A1, typename A2, typename A3>
void Attach(A1 a1, A2 a2, A3 a3);

template<typename A1, typename A3, typename A4>
void Attach(A1 a1, A2 a2, A3 a3, A4 a4);
+2

Source: https://habr.com/ru/post/1760520/


All Articles