Ive been learning about lambdas and function pointers lately and wanted to use them in a simple callback system.
The map that stores an event and all callbacks that should be called when it gets triggered looks like this:
std::unordered_map< sf::Event::EventType , std::vector< Callback > > eventMap;
.
I defined Callback this way
typedef void(*Callback)(sf::Event const&);
. My registerEvent()
function takes an event and a Callback as arguments.
registerEvent()
can then be called this way:
inputHandler.registerEvent(/*Any event type*/, [](sf::Event const&)
{
//do something
});
That works fine but when I want to capture an object I get an compile error saying
error: no matching function for call to ‘InputHandler::registerEvent(sf::Event::EventType, Button::Button(ID, Callback, InputHandler&)::<lambda(const sf::Event&)>)’
The code that produces that error is the following:
class Button
{
//
public:
Button(ID id, Callback callback, InputHandler& inputhandler)
{
inputhandler.registerEvent(sf::Event::MouseButtonPressed, [this](sf::Event const&)
{
{
getTextureRect();
}
});
}
};
It seems as if the this
capture is changing the type of the lambda, which makes it incompatible with the registerEvent()
function. But since lots of different classes should be able to create such lambdas and also lambdas without any capture should be contained in the vector, I don't know how to tell what type the vector should be. I heard of std::function
but (this may sound silly) I would like to use the C-Style way in order to get a better understanding. I think this post says something about that but I don't quite understand it that well. I thought about creating two maps, one for all capture-less lambdas and one for the others. Then I could let every class inherit from a base class and make the capture type in the vector a pointer to the base class, though this is pretty complex and adds unnecessary overhead and I don't even know if this would work.
What is the general solution for a situation like this one?
Thanks for all replies and best regards,
Daniel Schreiber Mendes :)
Edit:
Callback now looks like this:
typedef std::function< void(sf::Event const&) > Callback;
And when I want to use it:
//inside the Button Constructor
inputhandler.registerEvent(sf::Event::MouseButtonPressed, Callback([this](sf::Event const& event)
{
//memberFunc();
}));
This did not give me an error but behaved in a wrong way. It did execute the lambda, but it didn't change the class in which it was defined. So I added a line in the constructor which just prints the address of the just created object. I am creating only one Button, so there should be only one adress printed. But there were two different. That means when inserting the lambda wrapped in a std::function into a vector, a new Button object gets created. How can that be? An implicit Object creation?
Thanks for your answers :)