使用boost进行函数式编程:将boost :: bind传递给boost :: bind

时间:2014-04-25 21:22:48

标签: c++ function boost functional-programming boost-bind

我正在尝试对我正在编写的一些代码采用函数式方法。特别是,我想将一个函数传递给另一个函数,该函数对它做了一些事情,然后在boost::asio::io_service上安排后一个函数。

我尝试了以下内容(灵感来自io_service.hppio_service::post的定义为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;
}

但我明白了:

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

随后有大量候选人。

2 个答案:

答案 0 :(得分:2)

问题是您正在尝试绑定到模板函数,这不起作用。你可以通过用here所描述的仿函数替换foo_then_smile来解决这个问题。

但是它的价值;如果您使用的编译器支持C ++ 11,则通常可以使用lambdas代替绑定。我发现他们的语法更清晰,更具可读性,他们会让你对你遇到的问题进行最终的解决:

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

答案 1 :(得分:1)

如果你不能使用c ++ 11,你可以将函数模板变成一个多态函数对象:

struct foo_then_smile
{
    typedef void result_type;

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

并使用它(注意 protect以避免混淆绑定解包):

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

查看 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();
}

打印:

The important answer is 6
Smile!