#include <iostream>
#include <functional>

namespace sf { using Event = int ; }

class event_callback
{
    std::function< bool( const sf::Event& ) > func;

    public:
        template< typename FN, typename... ADDITIONAL_ARGS >
        event_callback( FN f, ADDITIONAL_ARGS... additional_args )
          : func { std::bind( f, std::placeholders::_1, additional_args... ) } {}

    bool run(const sf::Event& evt) { return func(evt); }
};

struct A
{
    bool mem_fun( const sf::Event& ) { return std::cout << "A::mem_fun\n" ; }
    bool mem_fun_with_more_args( sf::Event, int, char )
    { return std::cout << "A::mem_fun_with_more_args\n" ; }
};

int free_fun( sf::Event e, A& a, double d )
{
    // ...
    std::cout <<  "free_fun => " ;
    return a.mem_fun_with_more_args( e, d, 'H' ) ;
}

bool logger( sf::Event ) { std::cout << "just log the event\n" ; return true ; }

int main()
{
    A a ;

    event_callback cb{ std::bind( &A::mem_fun, &a, std::placeholders::_1 ) } ;
    cb.run(30) ;

    cb = std::bind( &A::mem_fun_with_more_args, &a, std::placeholders::_1, 78, 'D' ) ;
    cb.run(30) ;

    cb = std::bind( free_fun, std::placeholders::_1, std::ref(a), 23.5 ) ;
    cb.run(30) ;

    cb = [&a]( sf::Event x ) { std::cout << "closure => " ; return a.mem_fun(x) ; } ;
    cb.run(30) ;

    cb = logger ;
    cb.run(30) ;
}
