3
class Foo 
{
    double f1( int x, std::string s1 );
    double f2( int x, SomeClass s2 );
}

I want to be able to bind Foo.f1's s1 without an instance of foo to create in essense

typedef double (Foo::* MyFooFunc)( int ) 

MyFooFunc func1 = boost::bind( &Foo::f1, _1, _2, "some string" );
MyFooFunc func2 = boost::bind( &Foo::f2, _1, _2, SomeClass );

Then I pass func1 and func2 as parameters to other functions, inside which Foo is finally bound:

void SomeOtherFunction( MyFooFunc func )
{
     Foo foo;
     boost::function< double (int) > finalFunc =
          boost::bind( func, foo, _1 );
}

Questions: Is this possible? If yes, 1) how to achieve it? 2) What's the declaration of MyFooFunc?

2
  • It depends on SomeOtherFunction is declared. Note that your second typedef is not a function pointer, it's pointer-to-member-function (PTMF), which is an entirely different and incompatible concept. Wrapping everything in std::function or std::tr1::function or boost::function would probably be the most powerful solution. Commented Aug 5, 2011 at 14:31
  • There are actually two issues here: 1) binding PTMF without an instance. 2) express the result of the bind as boost function. For 1), I tried boost::bind( &Foo::f1, _1, _2, "hello" ). That didn't work. For 2), I suspect it's boost::function< int (boost::shared_ptr<Foo>,int) >. Commented Aug 5, 2011 at 14:53

2 Answers 2

4
typedef double (Foo::* MyFooFunc)( int );

MyFooFunc func1 = boost::bind( &Foo::f1, _1, _2, "some string" );

The result of boost::bind is not a pointer to member, so func1 cannot be initialized as such on the second line. The result of boost::bind is an unspecified type (which will depend on the parameters). If you're using C++0x, the simplest way to name the result of a call to bind is to use auto:

auto func1 = boost::bind( &Foo::f1, _1, _2, "some string" );

Another simple way (not restricted to C++03) is simply to not name the result, but to use it on the spot:

SomeOtherFunction(boost::bind(&Foo::f1, _1, _2, "some string"));

Or, you can use type-erasure to store the result of boost::bind into a boost::function, which you seem to be familiar with. boost::function<double(Foo&, int)> is a possibility but not the only choice.


We now need to find the appropriate signature for SomeOtherFunction: again, a pointer to member can't be initialized from the result of a call to boost::bind, so void SomeOtherFunction(MyFooFunc func); won't work. You can make the function a template instead:

template<typename Func>
void SomeOtherFunction( Func func )
{
     Foo foo;
     boost::function< double (int) > finalFunc =
          boost::bind( func, foo, _1 );
}

If a template is not preferrable, then you must use some kind of type-erasure such as, again, boost::function.

void SomeOtherFunction(boost::function<double(Foo&, int)> const& func);

(once again other boost::function types are possible depending on details such as passing a ref-to-const as opposed to a ref-to-non-const)

Sign up to request clarification or add additional context in comments.

Comments

0

Try this:

boost::bind(&Foo::f1, object, _1, _2);

object is an instance of class Foo. _1 and _2 are the argument placeholders.

3 Comments

There's probably just one placeholder, since the OP wants Foo::f1(int) I think...
Note that if object is a value and not a pointer, you should do boost::ref(object) or &object, otherwise binder will operate on a copy.
Sorry for the confusion. I want to separate the binding of an instance of Foo (object) and the non uniform parameters (s1,s2) into 2 steps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.