Reputation: 119
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
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
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