Frage

I'm attempting to take a functional approach to some code I am writing. In particular, I want to pass a function to another function which does something with it, and to then schedule that latter function on a boost::asio::io_service.

I tried the following (inspired by io_service.hpp's definition of io_service::post) as template <typename CompletionHandler> void post(CompletionHandler handler);):

#include <stdio.h>

#include <boost/asio/io_service.hpp>
#include <boost/bind.hpp>

template <typename FUNC>
void foo_then_smile(FUNC handler) {
    handler();
    printf("Smile!\n");
}

void foo(int a, int b, int c) {
    printf("The important answer is %d\n", a + b + c);
}

int main() {
    boost::asio::io_service ioService;

    ioService.post(boost::bind(foo_then_smile, boost::bind(foo, 1, 2, 3)));

    return 0;
}

But I get:

no matching function for call to 'bind(<unresolved overloaded function type>, boost::_bi::bind_t<void, void (*)(int, int, int), boost::_bi::list3<boost::_bi::value<int>, boost::_bi::value<int>, boost::_bi::value<int> > >)'

Followed by a huge list of candidates.

War es hilfreich?

Lösung 2

And if you can't use c++11, you can turn the function template into a polymorphic function object:

struct foo_then_smile
{
    typedef void result_type;

    template <typename FUNC>
        void operator()(FUNC handler) const {
            handler();
            printf("Smile!\n");
        }
};

And use it (note the protect to avoid mixing up the bind unwrappings):

ioService.post(boost::bind(foo_then_smile(), 
               boost::protect(boost::bind(foo, 1, 2, 3))));

See it Live On Coliru

#include <stdio.h>

#include <boost/asio/io_service.hpp>
#include <boost/bind.hpp>
#include <boost/bind/protect.hpp>

struct foo_then_smile
{
    typedef void result_type;

    template <typename FUNC>
        void operator()(FUNC handler) const {
            handler();
            printf("Smile!\n");
        }
};

void foo(int a, int b, int c) {
    printf("The important answer is %d\n", a + b + c);
}

int main() {
    boost::asio::io_service ioService;

    ioService.post(boost::bind(foo_then_smile(), boost::protect(boost::bind(foo, 1, 2, 3))));

    ioService.run();
}

Prints:

The important answer is 6
Smile!

Andere Tipps

The problem is that you are trying to bind to a template function, which doesn't work. You can get around this by replacing foo_then_smile with a functor as described here.

But for what it's worth; if the compiler you're using supports C++11, you can typically use lambdas in place of bindings. I find their syntax to be cleaner and more readable, and they would let you do an end-run around the problem you're experiencing:

ioService.post([]() { foo_then_smile( []() { foo(1, 2, 3); } ); });

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top