Question

I have written an event class template dessigned to provide C#-style events: Event instances are stored as public members of classes to provide different events to the owner class. For example:

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();
}

The output is:

Lambda!
On event_a of class foo!
Catching an event with a member function!

Now I want to use that mechanisms to wrap freeglut with a OO-style. Specifically, I wan't to write a class responsible of managing the different freeglut events (Window resizing, keyboard input, mouse movement, etc).
My first idea was to use the class constructor to register one lambda for each freeglut callback, and the lambda bypasses the argumments of the callback to the appropiated event, like this:

class freeglut_events
{
    event<freeglut_events> repaint_event;

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

But this leads to the following compiler error (I'm using Visual Studio 2012):

There is no valid conversion from '[]lambda() -> void' to 'void(*)()'

What I understand is that the signature of the global function pointer which the registration function expects and the signature of the lambda are not exactly equal, because the lambda captures local data.

My question is: Is there any other elegant way to achieve this?

Was it helpful?

Solution

Well, you cannot do that. As only non-capturing lambdas can be converted to function pointers, and the glutDisplayFunc takes a function pointer parameter, namely void (*func)(void) .

Also see this answer: Passing 1 argument (pointer) to glutDisplayFunc?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top