【发布时间】:2010-08-19 12:11:42
【问题描述】:
我有一个带有“附加”函数的类,它接受一个函数对象并将其存储到一个集合中。类本身是在函数签名上模板化的。像这样的:
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 将神奇地与 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 等用于模板化@987654340 的函数原型所隐含的@班级?
【问题讨论】:
-
您是否尝试使用 Google/Bing 进行“完美转发”?假设你可以使用 C++0x。
-
我现在正在查看它,例如这里:open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm。我不清楚这如何有助于解决问题。
标签: c++ events bind variadic-templates variadic-functions