2

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 signatures. 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()>&)

3 Answers 3

6

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.

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

Comments

2

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.

Comments

1

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).

2 Comments

For boost function, the scenario is even more evil than this. It's like template<typename T> struct A { template<typename U> A(U); }; now, that looks unsolvable to me xD Note that you can convert if you had only one function. The difficulty is to compare two such conversion sequences. In the boost::function case, this is downright impossible, and in your case, it could be possible but it's too complex for over-res to bother with.
@Johannes Schaub: You are right. My example was illustrating a completely different problem: ambiguity instead of "unsolvability" :)

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.