嵌套boost :: bind与io_service :: post

时间:2014-06-11 11:57:09

标签: c++ multithreading boost boost-asio

我的问题的简短版本:

当我尝试像这样提升:: bind io_service :: post时:

boost::bind(&boost::asio_io_service::post, &ios,
        boost::bind(&MyClass::func, this, arg1, arg2));

我得到这样的错误:

error: no matching function for call to ‘bind(<unresolved overloaded function type>,
boost::asio::io_service*, boost::_bi::bind_t<void, boost::_mfi::mf2<void, MyClass,
const char*, const char*>, boost::_bi::list3<boost::_bi::value<MyClass*>,
boost::_bi::value<const char*>, boost::_bi::value<const char*> > >)’

我该如何解决这个问题?

非常简单的测试代码:http://pastebin.com/V0uyLywC

我的问题的长版:

我试图编写一个通用事件队列类,您可以将不同类型的事件添加到队列中。您可以按类型订阅事件,当添加该类型的事件时,将调用订阅的回调函数。

事件队列对象可能由来自不同io_services的不同线程组订阅。使用boost :: lockfree:queue或boost :: interprocess :: message_queue(如果将来会进行进程间处理),此类的内部队列将是线程安全的。并且订阅的回调函数需要由其相应的io_service帖子调用,因此尝试嵌套的boost :: bind在上面。

这是一个好的和可行的设计吗?

假设这种方法可行,我认为当你订阅时,另一种选择也会传递io_service,但我在想1)也许这个类可以在不涉及io_services时使用,2)这个类不应该&# 39;我需要了解io_service。

谢谢大家。

P.S。我看过boost::bind composition inside io_service::post function,但感觉与我的问题有点不同。

2 个答案:

答案 0 :(得分:2)

更新所有解决方案 Live On Coliru

问题

第一个问题是post有重载,所以你需要消除歧义。这太丑了:

boost::bind(
    static_cast<void (boost::asio::io_service::*)
        (
            boost::_bi::protected_bind_t<
                boost::_bi::bind_t<
                    void, 
                    boost::_mfi::mf2<void, MyClass, int, int>,
                    boost::_bi::list3<boost::_bi::value<MyClass *>,
                    boost::_bi::value<int>,
                    boost::_bi::value<int>
                >
            > > const&
        )>(&boost::asio::io_service::post), 
    &ios_, 
    boost::protect(boost::bind(&MyClass::func, this, 7, 42)));

当然,你可以尝试使用decltype和一些typedef:

auto nested = boost::protect(boost::bind(&MyClass::func, this, 7, 42));
typedef decltype(nested) actual_t; // _bi::protected_bind_t<bind_t<void, mf2<void, MyClass, int, int>, list3<value<MyClass *>, value<int>, value<int> > > >
typedef void (boost::asio::io_service::*pmf)(actual_t const&);
boost::bind(static_cast<pmf>(&boost::asio::io_service::post), &ios_, nested);

但这首先会或多或少地反驳内联绑定表达式的目的。


解决方案

或者你可以使用一个帮助函子,它隐藏了一个合适的多态operator()后面的重载集:

boost::bind(poster(ios_),
            boost::protect(boost::bind(&MyClass::func, this, 7, 42)));

poster帮助器的位置

struct poster {
    typedef void result_type;

    poster(boost::asio::io_service& ios) : ios_(ios) {}
    boost::asio::io_service& ios_;

    template<typename F> void operator()(F const& f) const {
        ios_.post(f);
    }

    template<typename F> void operator()(F&& f) const {
        ios_.post(std::move(f));
    }
};

答案 1 :(得分:0)

当然,您尝试做的事情很简单:

std::function<void()> f = [this, arg1, arg2]() {
  ios_.post([this, arg1, arg2]() {
    this->func(arg1, arg2);
  });
};

现在你的主题可以调用f(),这会做正确的事情......

或者我错过了什么......