Boost::Bind and the Forwarding Problem

Started by
7 comments, last by daerid 19 years, 6 months ago
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...)

Drew Sikora
Executive Producer
GameDev.net

Advertisement
seems like that VC2005 is a wee bit on the BETA SIDE :)
you should switch back till its realeased :p

/sorry im no use...
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
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...

Drew Sikora
Executive Producer
GameDev.net

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?
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
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.
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...

Drew Sikora
Executive Producer
GameDev.net

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;}
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
You da man Fruny [smile]

rating++

Drew Sikora
Executive Producer
GameDev.net

Yeah, Fruny rawks

++e-suckup rating;
daerid@gmail.com

This topic is closed to new replies.

Advertisement