Perform argument substitution on nested boost::bind without composition

落爺英雄遲暮 提交于 2019-11-30 15:29:21

Interesting question...

What you basically want is a "bound call to bind". In the same manner than binding a call to foo(x, y) is written bind(&foo, x, y), binding a call to bind(&foo, x) should be like bind(&bind, &foo, x). However, taking the address of an overloaded function quickly gets ugly and, as boost::bind has more overloads than I could count, it gets pretty ugly:

// 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
  )
);

You'll probably agree that, while "interesting", the above won't win readability contests. Separating the obtention of the proper bind overload from the rest makes things a bit more manageable:

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

but I still hesitate to recommend it ;)

Edit:

Answering the OP's comment about how/if C++0x would help to clean the syntax: It does:

auto f = [](int i){enqueue([=](){foo(i);});};

'Nest' manually:

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);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!