0

I'm using boost::function like this:

template<class T1>
void run(boost::function<void (T1)> func, string arg)
{
    T1 p1 = parse<T1>(arg);
    func(p1);
}

When used like this, everything is ok:

void test1(int i)
{
    cout << "test1 i=" << i << endl;
}

...

boost::function<void (int)> f = &test1;
run(f, "42");

I want to be able to pass the raw function pointer directly, so I overload the run() function like this:

template<class T1>
void run(void (*func)(T1), string arg)
{
    T1 p1 = parse<T1>(arg);
    (*func)(p1);
}

...

run(&test1, "42"); // this is OK now

Now, I want to be able to pass the result of boost::bind to the run() function. Like this:

void test2(int i, string s)
{
    cout << "test2 i=" << i << " s=" << s << endl;
}

...

run(boost::bind(&test2, _1, "test"), "42"); // Edit: Added missing parameter 42

But this wont compile: Edited

bind.cpp: In function ‘int main()’:
bind.cpp:33:59: error: no matching function for call to ‘run(boost::_bi::bind_t<void, void (*)(int, std::basic_string<char>), boost::_bi::list2<boost::arg<1>, boost::_bi::value<std::basic_string<char> > > >, std::string)’
bind.cpp:33:59: note: candidates are:
bind.cpp:7:6: note: template<class T1> void run(boost::function<void(T1)>, std::string)
bind.cpp:14:6: note: template<class T1> void run(void (*)(T1), std::string)

How should I overload run() to accept boost::bind()?

Edit 2

I know I can do it like this:

boost::function<void (int)> f = boost::bind(&test2, _1, string("test"));
run(f, "42");

But I'd like the usage to be less verbose.

Edit 3

Changed run() prototype from run(boost::function<void (T1)>, T1) to run(boost::function<void (T1)>, string) to elaborate the actual use case. Ref. Igor R.'s answer

The entire source file may be obtained here

2
  • There is no such thing as an "implicit cast". A cast is something you write in your source code to tell the compiler to do a conversion. There are conversions that the compiler can do without a cast; such a conversion is an "implicit conversion". When you use a cast it is an "explicit conversion". Commented Apr 9, 2013 at 10:03
  • Indeed. The question title should be changed. Commented Apr 9, 2013 at 11:05

1 Answer 1

1

Neither function nor the result type of bind are convertible to a function pointer, so you can't pass them to run function with its current signature.

However, you can change run signature to allow it accepting any callable:

template<class F, class A1>
void run(F f, A1 arg)
{
  f(arg);
}

Now you can pass a pointer function, a binder, boost::function or what ever callable you wish - as long as it expects 1 argument. (Note however, that with this trivial signature run wouldn't forward the arguments to f seamlessly.)

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

3 Comments

Yes, the solves the problem I have described (+1). However, the actual run() function needs to know the type of the argument and the argument is not part of the real world function.
The real world function uses the argument type to call a templated string parser so that I can call a function, giving it string arguments, and the run() function parses the arguments as correct types and invokes the function
@Dr. Sbaitso I.e., run should accept a callable that expects 1 argument of of type T, and this type should be automatically deduced from the signature of the actual callable passed to run? Well, at the moment I can't figure out how to do this. Without auto-deduction it would be quite trivial: ` template < class A1, class F > void run(F f, string a) { T1 p1 = parse < T1 > (a); f(p1); } ` Call like this: run < int > (test2, yourString);

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.