Интересный вопрос ...
То, что вы в основном хотите, это «связанный вызов связать». Таким же образом, как привязка вызова к 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));
но я все еще не решаюсь рекомендовать его;)
Edit:
Ответ на комментарий ОП о том, как / если C ++ 0x поможет очистить синтаксис: Это делает:
auto f = [](int i){enqueue([=](){foo(i);});};