Sign in to follow this  
Gaiiden

Boost::Bind and the Forwarding Problem

Recommended Posts

So I want to create a callback function for my game objects as they handle messages so that game-specific actions can be taken. Clash pointed me toward the Boost Function and Bind libraries. Good stuff. The only problem I have is binding a function that has an argument. I of course would like to pass along the message currently being handled, after all. However it seems that if I were to create a callback like so:
typedef boost::function<void(DataPtr)> Callback;
and bind it like so:
obj->SetUserUpdateFunction(boost::bind(&CUIMngr::UpdateUI, UIManager));
Not only do I get a compiler warning: ..\mem_fn.hpp(256) : warning C4180: qualifier applied to function type has no meaning; ignored But the VC++ Express compiler actually crashes. Every time. I thought maybe I was calling bind() wrong, so I used the test code from the docs, and it compiled fine. Then on a hunch, I added an argument to the callback function and crash! boom! bang! So I went back over the Boost::Bind docs and the only thing I could find was the reference to the Forwarding Problem. Does this mean I can't bind any functions with arguments? Or that I have to do a bit of hacking to get it to work properly? Or am I totally off the mark, you can bind functions with arguments, and I'm missing somethign completely stupid? (wouldn't be the first time...)

Share this post


Link to post
Share on other sites
Yea that's another thing. Good point. So you're saying that you've been able to use bind with arguments yourself? Or you just think that's the problem? It could be...

Share this post


Link to post
Share on other sites
Quote:
Original post by Gaiiden
Yea that's another thing. Good point. So you're saying that you've been able to use bind with arguments yourself? Or you just think that's the problem? It could be...


Well, binding arguments is, after all, the whole point of boost::bind, so if it didn't work there would be something very wrong going on.

For what it's worth, I haven't had problems with it on VC7.1 nor on gcc.

What kind of parameter did you try to pass?

Have you considered the boost::signal library instead for callbacks?

Share this post


Link to post
Share on other sites
Have you added the define __WIN32__ to your project's preprocessor definitions? that usually sorts things out for me

Also if your not binding something complicated you could try and use the standard library binders but they are a little messed up hence the reason for boost having there own.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
What kind of parameter did you try to pass?

Well, I'm passing a boost::smart_ptr in the actual implimentation, but the test code I was using just passed an int.
Quote:

Have you considered the boost::signal library instead for callbacks?

Nope. I'll look into it.

In the meantime, here's the code that's causing VC++ Express to throw fits in case anyone wants to throw together a quick Win32 console project and test it out

#include "boost/function.hpp"
#include "boost/bind.hpp"

class button
{
public:

boost::function<void (int)> onClick;
};

class player
{
public:

void play(int) {}
void stop(int) {}
};

button playButton, stopButton;
player thePlayer;

void connect()
{
playButton.onClick = boost::bind(&player::play, &thePlayer);
stopButton.onClick = boost::bind(&player::stop, &thePlayer);
}

int main()
{
connect();

return 1;
}



Quote:
Original post by snk_kid
Have you added the define __WIN32__ to your project's preprocessor definitions? that usually sorts things out for me

I'll check to see, and if not I'll give it a shot...

Share this post


Link to post
Share on other sites
Quote:
Original post by Gaiiden
In the meantime, here's the code that's causing VC++ Express to throw fits in case anyone wants to throw together a quick Win32 console project and test it out
*** Source Snippet Removed ***


Yeah, that's exactly what boost::signal is intended to deal with. It even allows you to connect multiple callbacks to a single button. :)

And in your code snippet, you've forgotten to add the _1 placeholder for the int parameter itself. With a 2 (remaining) parameter function, you would have _1 and _2, and so on. They indicate where in the original function would the parameters you provide to the functor would go.

I added a using namespace boost; because I can't remember where exactly the _1 is, namespace-wise, and that way it works:


#include "boost/function.hpp"
#include "boost/bind.hpp"

class button
{
public:

boost::function<void (int)> onClick;
};

class player
{
public:

void play(int) {}
void stop(int) {}
};

button playButton, stopButton;
player thePlayer;

void connect()
{
using namespace boost;

playButton.onClick = boost::bind(&player::play, &thePlayer, _1);
stopButton.onClick = boost::bind(&player::stop, &thePlayer, _1);
}

int main()
{
connect();

return 1;
}




Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this