dwaksman
dwaksman

Reputation: 119

std::bind "no matching function for call"

I am trying to set a delegate for a function and have the 2 following classes to achieve that.
On the bottom is the error I'm getting. How do I handle it?

Class A

typedef void (*SocketEventString) (String);

class SocketIO 
{
    public:
        SocketIO();
        void onMessage(SocketEventString _cb);


    private:
        SocketEventString _onMessage;

};

Class B

class BoardManager 
    {
        public:
            BoardManager();
            void handleAction(String action);
            SocketIO io;
    };

//Constructor
BoardManager::BoardManager() {

    io.onMessage(  std::bind( &BoardManager::handleAction, this, std::placeholders::_1 ) );
}

ERROR

sketch/BoardManager.cpp: In member function 'void BoardManager::initializeSocketIO()':
BoardManager.cpp:68: error: no matching function for call to 'SocketIO::onMessage(std::_Bind_helper<false, void (BoardManager::*)(String), BoardManager* const, const std::_Placeholder<1>&>::type)'
     io.onMessage(  std::bind( &BoardManager::handleAction, this, std::placeholders::_1 ) );
                                                                                          ^
sketch/BoardManager.cpp:68:90: note: candidate is:
In file included from sketch/BoardManager.h:10:0,
                 from sketch/BoardManager.cpp:8:
sketch/SocketIO.h:25:18: note: void SocketIO::onMessage(SocketEventString)
             void onMessage(SocketEventString _cb);

Upvotes: 2

Views: 2932

Answers (2)

Some programmer dude
Some programmer dude

Reputation: 409176

The std::bind function return an object that is not compatible or convertible to a pointer to a non-member function.

Instead use std::function:

using SocketEventString = std::function<void(String)>;

With the definition

typedef void (*SocketEventString) (String);

you say that SocketEventString is a pointer to a non-member function (i.e. a function not a member in a class or struct) that takes one argument of type String and returns no value.

The std::bind function returns an object of an unknown class. That object is not the same a the pointer-type you define SocketEventString to be.

The two types (SocketEventString and the object returned by std::bind) are not compatible. You can not convert from one of the types to the other.

The compiler tell you this, because it tries to find a function SocketIO::onMessage which takes the type of the object returned by std::bind and don't find any such overload.

Instead of the SocketEventString type you have defined, you need to use type that is compatible with the object returned by std::bind. That's what I have shown above in my answer, defined SocketEventString to be a different type, a type that is compatible with the type returned by std::bind.

Upvotes: 7

mukunda
mukunda

Reputation: 2995

Firstly, you can't use a C function pointer for a C++ function binding like that. Essentially, when you use bind it captures some variables to be used in the function call (such as this), so you need to use std::function which handles capturing variables if you want to bind a member function (because member functions at the very least need the this pointer captured). Also, in my opinion, std::bind is fairly ugly, and I recommend getting familiar the new C++ lambdas.

BoardManager::BoardManager() {
    io.onMessage( [&]( String action ) {
        handleAction( action );
    });
}

Upvotes: 1

Related Questions