2013-10-12 48 views
2

我已经写了一个event类模板dessigned提供C#风格的事件:事件实例存储为类的公共成员,以提供不同的事件给所有者类。例如:最优雅的方式来包装类内的freeglut回调

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上!
用会员功能捕捉事件!

现在我想用这种机制来将Freeglut换成OO风格。具体而言,我不想写一个负责管理不同Freeglut事件(窗口大小调整,键盘输入,鼠标移动等)的类。
我的第一个想法是使用类的构造函数来注册每个freeglut回调一个拉姆达,和拉姆达绕过回调argumments到appropiated事件,像这样:

class freeglut_events 
{ 
    event<freeglut_events> repaint_event; 

    freeglut_events() 
    { 
     glutDisplayFunc([&](){ repaint_event.raise_event(*this); });     
    } 
}; 

但是,这导致了以下编译器错误(我使用Visual Studio 2012):

没有来自有效的转换 '[]拉姆达() - >无效' 到 '无效(*)()'

什么我明白是t他注册函数所期望的全局函数指针的签名和lambda的签名并不完全相等,因为lambda捕获本地数据。

我的问题是:是否有任何其他优雅的方式来实现这一目标?

+1

为[这里解释(http://stackoverflow.com/a/18889029)转换为一个函数指针(因此'+'招)仅适用于* *不捕获** lambda。 –

+0

@DanielFrey感谢您的信息,我没有考虑过。有其他选择吗? – Manu343726

+0

恐怕不是。 –

回答