问题
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?
回答1:
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)
回答2:
Try this:
boost::bind(&Foo::f1, object, _1, _2);
object
is an instance of class Foo.
_1 and _2 are the argument placeholders.
来源:https://stackoverflow.com/questions/6957929/boost-bind-class-function-pointer