3

I'm trying to shoehorn in some boost::bind to substitute member functions for straight up C function pointer style callbacks, but I'm running into problems doing the obvious thing. Can someone tell me why the following code snippet can't seem to match up the types in the function call?

#include <iostream>
#include <boost/bind.hpp>

using namespace std;

class Foo {
public:
  Foo(const string &prefix) : prefix_(prefix) {}
  void bar(const string &message)
  {
    cout << prefix_ << message << endl;
  }
private:
  const string &prefix_;
};

static void
runit(void (*torun)(const string &message), const string &message)
{
  torun(message);
}

int
main(int argc, const char *argv[])
{
  Foo foo("Hello ");
  runit(boost::bind<void>(&Foo::bar, boost::ref(foo), _1), "World!");
}
3
  • 1
    Why would you do this? What benefit are you trying to achieve? Commented Jul 7, 2011 at 20:58
  • @AJG85 - I have a C library that is used by multiple C programs (which precludes me from modifying the headers/implementation) and I want to develop a new C++ program using some of the provided functionality. In particular there are places where I want to call one of a possible set of library functions (with identical signatures save the function name) through a generic callback mechanism. Commented Aug 16, 2011 at 7:30
  • Ah well a typedef of a boost::function and a function that takes a const& to the typedef in a namespace ought to work if you must. Then you can use boost::bind when calling the namespace function with whatever you want. Commented Aug 16, 2011 at 15:38

4 Answers 4

4

The result type of bind is not a function pointer, it's a function object which does not happen to be implicitly convertible to a function pointer. Use a template:

template<typename ToRunT>
void runit(ToRunT const& torun, std::string const& message)
{
    torun(message);
}

Or use boost::function<>:

static void runit(boost::function<void(std::string const&)> const& torun,
                  std::string const& message)
{
    torun(message);
}
Sign up to request clarification or add additional context in comments.

2 Comments

The actual term for it is bind_expression (see the related is_http://msdn.microsoft.com/en-us/library/bb981965.aspx mpl predicate)
Tested both of these methods and they worked just fine. Thanks!
2

Rather than having a specific function pointer signature for your first argument to runit, use a template. So for instance:

template<typename function_ptr>
void runit(function_ptr torun, const string &message)
{
  torun(message);
}

Comments

1

You can use boost::function type for boost::bind objects

Comments

0

Pasting the error you get could be useful; however at a guess it's probably due to the fact that "World!" is a string literal (i.e. char[]), not a std::string. Try:

runit(boost::bind<void>(&Foo::bar, boost::ref(foo)), std::string("World!"));

1 Comment

implicit conversion will take place via copy constructor overloads on std::string

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.