我编写了一个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();
}
输出是:
拉姆达!
在 foo 类的 event_a 上!
使用成员函数捕捉事件!
现在我想使用该机制以 OO 样式包装 freeglut。具体来说,我不想编写一个类来负责管理不同的 freeglut 事件(窗口大小调整、键盘输入、鼠标移动等)。
我的第一个想法是使用类构造函数为每个 freeglut 回调注册一个 lambda,并且 lambda 绕过回调的参数到适当的事件,如下所示:
class freeglut_events
{
event<freeglut_events> repaint_event;
freeglut_events()
{
glutDisplayFunc( [&](){ repaint_event.raise_event( *this ); } );
}
};
但这会导致以下编译器错误(我使用的是 Visual Studio 2012):
没有从 '[]lambda() -> void' 到 'void(*)()' 的有效转换
我的理解是,注册函数期望的全局函数指针的签名和 lambda 的签名并不完全相等,因为 lambda 捕获本地数据。
我的问题是:有没有其他优雅的方式来实现这一目标?