I have to pass function into pointer. For this purposes I'm using boost::function. The function which catches the pointer is overloaded for different sig开发者_运维百科natures. For example:
void Foo(boost::function<int ()>) { ... }
void Foo(boost::function<float ()>) { ... }
void Foo(boost::function<double ()>) { ... }
Now I wanna pass some class-method pointer there:
class test
{
public:
float toCall() { };
};
class Wrapper
{
Wrapper() {
test obj;
Foo(boost::bind(&test::toCall, this));
}
};
error: no matching function for call to ‘Foo(boost::_bi::bind_t<float, boost::_mfi::mf0<float, test>, boost::_bi::list1<boost::_bi::value<Wrapper*> > >)’
note: candidates are: Foo(boost::function<float()>&)
Nonono this cannot work. Because boost::function<...>
has a templated constructor to accept any and all types. Compatibility with the call signature is checked later on. Overload resolution cannot resolve this.
Also, i think you want to pass &obj
instead of this
. Try converting explicitly:
Foo(boost::function<float ()>(boost::bind(&test::toCall, &obj)));
This is utterly ugly though so you may want to introduce a typedef
void Foo(FloatHandler) { ... }
...
FloatHandler f(boost::bind(&test::toCall, &obj));
Foo(f);
Or ultimately you could make Foo
a template that accepts just any callable type T
. I suspect that may be the simplest, because in the general case i suspect you don't know to what boost::function<...>
you need to cast to. And how about folks that want to return a std::complex<>
. So...
template<typename T>
void Foo(T) { ... }
...
Foo(boost::bind(&test::toCall, &obj));
Hope this helps.
In the line
Foo(boost::bind(&test::toCall, this));
this
is of type Wrapper
. But the bind can't find a toCall
method on it.
Here's a fixed-up version (complete, compiles on g++ 4.3.2) which is probably what you're trying to do:
#include <boost/bind.hpp>
#include <boost/function.hpp>
void Foo(boost::function<int()>) {}
void Foo(boost::function<float()>) {}
void Foo(boost::function<double()>) {}
struct test {
float toCall() {return 0.0f;}
};
int main(int,char**) {
test obj;
boost::function<float()> tgt=boost::bind(&test::toCall,obj);
Foo(tgt);
return 0;
}
As AndreyT's answer notes, the return type of bind is... a bit odd, hence the explicit coercion to an appropriate function type.
boost::bind
does not return a boost::function
object. It returns an object of unspecified type that can be used as a functor with corresponding number of parameters.
While boost::function
can be conversion-constructed from the result of boost::bind
, the overload resolution in this case is "too complex" for C++. (Removed my bad example which didn't really illustrate the right problem).
精彩评论