I have functions
void addOnHover(std::function<void(Button&, HoverState)>& func);
void addOnHover(void(*fptr)(Button&, HoverState));
Button inherits ButtonBase
, which is interface class and I want to pass
void hoverOver(game::ButtonBase& button, game::HoverState state)
{
static int i = 0;
if (state == game::HoverState::STATE_ENTER)
std::cout << "entered " << button.getLabel().getText().getString().toAnsiString() << " " << ++i << "\n";
else if (state == game::HoverState::STATE_LEAVE)
std::cout << "left " << button.getLabel().getText().getString().toAnsiString() << " " << ++i << "\n";
else
std::cout << "inside " << button.getLabel().getText().getString().toAnsiString() << " " << ++i << "\n";
}
lets say b
is of type Button
but if I do b.addOnHover(hoverOver);
it will not compile(some funky compiler error, as always with this kind of staff).
I can make it work if I do b.addOnHover(std::function<void(game::Button&, game::HoverState)>(hoverOver);
or if I change the hoverOver from taking game::ButtonBase&
to game::Button&
, but I wonder if it could be done without such verbosity(std::function...) and while keeping the argument as game::ButtonBase&
because there may be more Button classes in future
as per Bolov request, here is compiler error when passing hoverOver
1>Source.cpp(58): error C2664: 'void game::Button::addOnHover(std::function<_Fty> &)' : cannot convert parameter 1 from 'void (__cdecl *)(game::ButtonBase &,game::HoverState)' to 'std::function<_Fty> &'
1> with
1> [
1> _Fty=void (game::Button &,game::HoverState)
1> ]
edit:
One possible solution, even tho still pretty verbose is to add
template <class T, class C, class Q>
std::function<void(T&, C)> wrap(Q ptr)
{
return std::function<void(T&, C)>(ptr);
}
and call b.addOnHover(game::wrap<game::Button, game::HoverState>(hoverOver);
but Im not sure if it will function correctly yet