假设我有一个以nullary仿函数为参数的函数:
void enqueue( boost::function<void()> & functor );
我有另一个函数,它接受一个int并在内部做一些事情:
void foo( int a);
我想将这些一起嵌套,但不要编写,以便我得到一个带签名的仿函数:
boost::function<void(int)> functor
当使用值调用时 - 例如4 - 执行以下操作:
enqueue( boost::bind(&foo, 4) )
我的第一次尝试如下:
boost::function<void(int)> functor = boost::bind(&enqueue, boost::bind(&foo,_1))
这会失败,因为绑定在给定嵌套绑定时执行合成。 foo首先被调用,然后值void被“返回”到入队,但是失败了。
我的第二次尝试如下:
boost::function<void(int)> functor = boost::bind(&enqueue, boost::protect( boost::bind(&foo, _1) ) )
这失败了,因为enqueue接受了一个假的,而不是一元的函子。
我正在寻找的是什么?
其他信息:
答案 0 :(得分:4)
有趣的问题......
你基本上想要的是“绑定绑定”。以与绑定foo(x, y)
bind(&foo, x, y)
的约束相同的方式,绑定对bind(&foo, x)
的调用应该与bind(&bind, &foo, x)
类似。但是,获取重载函数的地址很快就会变得很丑陋,因为boost::bind
的重载次数超出了我的计算范围,所以它变得非常难看:
// One single line, broken for "readability"
boost::function<void(int)> f = boost::bind(
&enqueue,
boost::bind(
static_cast<
boost::_bi::bind_t<
void, void(*)(int), boost::_bi::list_av_1<int>::type
>
(*)(void(*)(int), int)
>(&boost::bind),
&foo,
_1
)
);
你可能会同意,虽然“有趣”,但上述内容不会赢得可读性竞赛。将正确的绑定重载与其他绑定的分离分开会使事情更容易管理:
boost::_bi::bind_t<void, void(*)(int), boost::_bi::list_av_1<int>::type>
(*bind_foo)(void(*)(int), int) = &boost::bind;
boost::function<void(int)> q = boost::bind(&enqueue, boost::bind(bind_foo, &foo, _1));
但我仍然犹豫推荐它;)
修改强>
回答OP关于如何/如果C ++ 0x有助于清除语法的评论:它确实:
auto f = [](int i){enqueue([=](){foo(i);});};
答案 1 :(得分:0)
'Nest':
class Enqueuer {
std::function<void (int)> mFunc;
public:
void operator()(int pVal) {
enqueue(std::bind(mFunc, pVal));
}
Enqueuer(std::function<void (int)> pFunc)
: mFunc(pFunc) {}
};
// usage:
Enqueuer e(foo);
e(1);
e(2);
e(3);