我正在尝试对我正在编写的一些代码采用函数式方法。特别是,我想将一个函数传递给另一个函数,该函数对它做了一些事情,然后在boost::asio::io_service
上安排后一个函数。
我尝试了以下内容(灵感来自io_service.hpp的io_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> > >)'
随后有大量候选人。
答案 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))));
#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!