我编写了一个event
类模板,用于提供C#样式事件:事件实例存储为类的公共成员,以向所有者类提供不同的事件。例如:
template<typename SENDER , typename ARGS>
class event{ .... };
struct foo
{
event<foo,int> event_a;
...
void do_work()
{
int data;
....
event_a.raise_event( *this , a );
}
};
void on_event_a(foo& , int&) { std::cout << "On event_a of class foo!" << std::endl; }
struct bar
{
void on_event_a(int&) { std::cout << "Catching an event with a member function!"; }
};
int main()
{
int argumment;
foo foo_instance;
bar bar_instance;
foo.event_a.add_handler( [](foo& , int& ) { std::cout << "Lambda!" << std::endl; } );
foo.event_a.add_handler( on_event_a );
foo.event_a.add_handler( bar_instance , &bar::on_event_a );
foo_instance.do_work();
}
输出结果为:
LAMBDA!
关于foo的event_a!
使用成员函数捕获事件!
现在我想使用这种机制用OO风格包装freeglut。具体来说,我不想写一个负责管理不同freeglut事件的类(窗口大小调整,键盘输入,鼠标移动等)。
我的第一个想法是使用类构造函数为每个freeglut回调注册一个lambda,lambda绕过适当事件的回调的argumments,如下所示:
class freeglut_events
{
event<freeglut_events> repaint_event;
freeglut_events()
{
glutDisplayFunc( [&](){ repaint_event.raise_event( *this ); } );
}
};
但这会导致以下编译器错误(我正在使用Visual Studio 2012):
'[] lambda() - &gt;没有有效转换void'to'void(*)()'
我理解的是注册函数所期望的全局函数指针的签名和lambda的签名不完全相等,因为lambda捕获本地数据。
我的问题是:还有其他优雅的方法来实现这一目标吗?