# Problems using boost::bind

## Recommended Posts

Hello I've run into a problem when using boost::bind, and I cannot figure why it wont compile. I'm using bind to create function bindings for my console system, so that the console can set and get variables of a class without the classes depending on eachother. My console has a ConsoleItem which has a boost::function<std::string (void)> get_function and boost::function<void (std::string)> set_function. From the console I can call Add, which then creates a ConsoleItem with functions as argument: void Add(std::string name, boost::function<void (std::string)> set_function, boost::function<std::string (void)> get_function). I can then create a ConsoleItem doing this:
Console con;
con.Add("name", bind(&ClassWithVariable::Variable, &X, bind(lexical_cast<int, std::string>, _1 )), bind( lexical_cast<std::string, int>, bind(&ClassWithVariable::Variable, &X)) );

Where the function Variable is int Variable(void) and void Variable(int) -- get and set respectively. I can now get and set via the console using the name as identifier and pass a string as argument for setting and do a boost::lexical_cast when getting. The problem however is that I am lazy and therefor I to create functions for adding each of the item types I can so that the interface is more like this:


// one of these functions for each type I can add.
// Possibly only named Add with different boost::function arguments
void AddInt(std::string name, boost::function<void (int)> set_function, boost::function<int (void)> get_function) {
Add(name, boost::bind(set_function, boost::lexical_cast<int, std::string>, _1), boost::bind(boost::lexical_cast<std::string, int>, get_function)); // does not compile
}


So that I can call add a console item like this:
Console con;
con.AddInt("hello", bind(&ClassWithVariable::Variable, &X, _1), bind(&ClassWithVariable::Variable, &X) );


The problem is, however, that the code with AddInt does not compile, and I have no idea why. Any help appreciated.

##### Share on other sites
Quote:
 Original post by dingojohnThe problem is, however, that the code with AddInt does not compile, and I have no idea why.
Can you post the error?

I only briefly glanced over your code, but I did notice that you (appear to) have overloaded member functions (the two versions of Variable) of which you're taking the address. Perhaps this is the cause of the problem.

##### Share on other sites
It does the same when I do not use overloaded member functions.

However, here is the error:

error C2664: 'std::string (const int &)' : cannot convert parameter 1 from 'boost::function<Signature>' to 'const int &'

##### Share on other sites
You have an error in last section, to be more specific

boost::bind(boost::lexical_cast<std::string, int>, get_function)

you bind function object to first parameter of lex_cast which is string.

##### Share on other sites
Quote:
 Original post by Toni PetrinaYou have an error in last section, to be more specific boost::bind(boost::lexical_cast, get_function)you bind function object to first parameter of lex_cast which is string.

Really? The function object takes no arguments and returns an int. I was quite sure it would be bound and then executed when the bound function is executed. Composition is quite possible, and I actually do it without problems with the old add function:

Console con;con.Add("name", bind(&ClassWithVariable::Variable, &X, bind(lexical_cast<int, std::string>, _1 )), bind( lexical_cast<std::string, int>, bind(&ClassWithVariable::Variable, &X)) );

It should be the same, considering that the ClassWithVariable.Variable is int Variable ( void )

Feel free to tell me if I misunderstood what you said or how bind works.

##### Share on other sites
Hmm, now I confused myself. Why don't you try compiling this.
boost::bind(set_function, boost::lexical_cast<int, std::string>, _1);boost::bind(boost::lexical_cast<std::string, int>, get_function);

Now check which statement doesn't compile. I'm gonna recheck myself tomorrow, gotta get some sleep.

##### Share on other sites
Actually, ofcourse it doesn't compile! It isn't same code. You bind the binder object at the wrong place. You don't get the same effect.

I don't get what exactly do you want to do so I'll try to figure out more tomorrow.

##### Share on other sites
What I am trying to do is quite simple. I want to create function bindings using the lexical_cast, so that the console internally can handle the functions with strings as argument.

void ClassWithVariable::Variable(int); is stored as a function<void, std::string> called set_function in the console. The function stored uses function composition through bind so that the console can call Variable( lexical_cast<int> (string) ) with set_function(string);

Just like that, the get function uses an approach that is quite like it:
int ClassWithVariable::Variable(void) is stored as a function<std::string, void> called get_function in the console It is done with boost::lexical_cast again, so that calling the get_function in the console results in calling boost::lexical_cast<std::string>( Variable() );.

It works like a charm with the Console.Add I have provided, however doing it with Console.AddInt doesn't work. All I've done is created a function that accepts another argument, and then converts it to what I want it to be. To me the composition looks right, due to the fact that I do what I do when callingthe Console.Add.

Any ideas?

##### Share on other sites
As far as I can see, problem is in the first part, originally you had
bind(&ClassWithVariable::Variable, &X, bind(lexical_cast<int, std::string>, _1 ))

now you have
boost::bind(set_function, boost::lexical_cast<int, std::string>, _1)set_function=bind(&ClassWithVariable::Variable, &X, _1)

shouldn't code be like this?
boost::bind(set_function, boost::bind(boost::lexical_cast<int, std::string>, _1))

That is why I said that your composition isn't right

##### Share on other sites
Quote:
 Really? The function object takes no arguments and returns an int. I was quite sure it would be bound and then executed when the bound function is executed. Composition is quite possible, and I actually do it without problems with the old add function:

IIRC (I haven't checked) this problem is known and documented in the boost.lambda documentation, to work around it you need to wrap the function object in boost::lambda::protect or something similar (I think, as I said I haven't checked and I'm not to sure about the specifics)

##### Share on other sites
I changed the AddInt function to

void AddInt(std::string name, boost::function<void (int)> set_function, boost::function<int (void)> get_function) 		{			Add(name, boost::bind(set_function, boost::bind(boost::lexical_cast<int, std::string>, _1)), boost::bind(boost::lexical_cast<std::string, int>, boost::bind(get_function)));		}

and now it seems to work. Thanks for the help, and nice catch Toni Petrina. It's really appreciated.

## Create an account

Register a new account

• ## Partner Spotlight

• ### Forum Statistics

• Total Topics
627664
• Total Posts
2978522

• 10
• 10
• 12
• 22
• 13