c++ - 嵌套 boost::bind 与 io_service::post

标签 c++ multithreading boost boost-asio

我的问题的简短版本:

当我尝试像这样 boost::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 的 post 来调用,因此尝试了上面的嵌套 boost::bind 。

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

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

谢谢大家。

附注我已阅读boost::bind composition inside io_service::post function但感觉与我的问题有点不同。

最佳答案

更新 所有解决方案 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);

但这或多或少会从一开始就反驳内联绑定(bind)表达式的目的。


解决方案

或者您可以使用辅助仿函数,它将重载集隐藏在合适的多态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));
    }
};

关于c++ - 嵌套 boost::bind 与 io_service::post,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24162360/

相关文章:

java - 基本多线程程序

Ruby/Glibc 核心转储(双重释放或损坏)

c++ - 使用 Boost.bimap 时如何避免键复制?

boost::smart_ptr 的 C++ 非侵入式 boost 序列化

C++ Boost Graph - 为什么我有一个额外的顶点?

c++ - boost make_shared 的用例

C++ 映射模板派生类

c++ - STL c++ 中不同类型列表声明的错误

c++ - 多继承与模板接口(interface)

multithreading - memcache 和 redis 的内部工作方式有何不同