namespace messaging { class close_queue {}; class dispatcher { queue* q; bool chained; dispatcher(dispatcher const&)=delete; dispatcher& operator=(dispatcher const&)=delete; template< typename Dispatcher, typename Msg, typename Func> friend class TemplateDispatcher; void wait_and_dispatch() { for(;;) { auto msg=q->wait_and_pop(); dispatch(msg); } } bool dispatch( std::shared_ptr const& msg) { if(dynamic_cast*>(msg.get())) { throw close_queue(); } return false; } public: dispatcher(dispatcher&& other): q(other.q),chained(other.chained) { other.chained=true; } explicit dispatcher(queue* q_): q(q_),chained(false) {} template TemplateDispatcher handle(Func&& f) { return TemplateDispatcher( q,this,std::forward(f)); } ~dispatcher() noexcept(false) { if(!chained) { wait_and_dispatch(); } } }; }