std::bind and std::function with template aguments

I'm trying to create a callback wrapper for pointers to member functions of any class by using templates, std::function and std::bind. This will be used to send incoming sf::Event's to classes who register callbacks with an event manager. I based my code off of the example on this page: http://en.cppreference.com/w/cpp/utility/functional/placeholders

Here's what I have:
1
2
3
4
5
6
7
8
9
10
class EventCallback
{
    std::function<bool(const sf::Event&)> func;

    public:
    template<typename T>
    EventCallback(T* object, bool(T::*func)(const sf::Event&)) { func = std::bind(func, object, std::placeholders::_1); }

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


MinGW throws:

Source\include\Events\WindowEventManager.hpp|15|error: cannot convert 'std::_Bind_helper<bool (MainMenuState::*&)(const sf::Event&), MainMenuState*&, const std::_Placeholder<1>&>::type {aka std::_Bind<std::_Mem_fn<bool (MainMenuState::*)(const sf::Event&)>(MainMenuState*, std::_Placeholder<1>)>}' to 'bool (MainMenuState::*)(const sf::Event&)' in assignment|
(it looks like CodeBlocks cut it off)

I'm not sure what I'm doing wrong, but I feel like it's something obvious and this crazy template error is throwing me off. Does anyone know what might be wrong here, or a better way to do this?
The parameter func hides the member func
Resolve the scope.
1
2
3
4
5
6
7
8
9
10
11
class EventCallback
{
    std::function<bool(const sf::Event&)> func;

    public:
    template<typename T>
    EventCallback(T* object, bool(T::*func)(const sf::Event&))
    { EventCallback::func = std::bind( func, object, std::placeholders::_1 ) ; }

    bool run(const sf::Event& evt) { return func(evt); }
};
o_0 Now don't I feel stupid. I knew it would be something like that :p Thank you!
Recommended (canonical, far more flexible):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#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) ;
}

http://ideone.com/nhpnWK
I don't think I'll have need for that much flexibility in the event callbacks, but thank you! That's certainly a lot better than anything I could have come up with.
Topic archived. No new replies allowed.