関数オブジェクトを受け入れてコレクションに格納する「アタッチ」関数を持つクラスがあります。クラス自体は、関数シグネチャでテンプレート化されています。このようなもの:
template<class Signature>
class Event
{
public:
void Attach(boost::function<Signature> signature)
{
MySignatures.push_back(signature);
}
private:
std::list<boost::function<Signature>> MySignatures;
};
使用法を示すために、次のクラスを検討してください。
class Listening
{
public:
int SomeFunction(int x, int y, int z);
};
関数を に渡すにはListening
、次のEvent
ように記述する必要があります。
Event<int(int, int, int)> myEvent;
Listening myListening;
myEvent.Attach(boost::bind(boost::mem_fn(&Listening::SomeFunction), &myListening, _1, _2, _3));
したがって、エラーが発生しやすいケースごとにそうする代わりに、次のように一連のマクロを記述します。
#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.
そして、私は書くことができます:
myEvent.Attach(EventArgument3(&Listening::SomeFunction, &myListening));
これははるかに読みやすいです(私は思う)。今私の質問に:代わりにどのように書くことができますか:
myEvent.Attach(EventArgument(&Listening::SomeFunction, &MyListening));
またはさらに良い:
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