阻止所有连接到升压信号的连接

时间:2010-08-06 11:49:28

标签: c++ boost boost-signals

增强信号允许通过连接成员函数暂时阻止连接。但是,我有一个有很多连接的信号。连接由各自的听众存储和维护。现在,广播公司决定暂时停止发送信号。似乎没有办法迭代信号的所有连接或暂时禁用整个信号。这对我来说似乎很奇怪,因为这样的机制必须在内部存在,以便信号在发出信号时到达所有用户...
我错过了什么吗?如何暂时禁用信号?

1 个答案:

答案 0 :(得分:2)

我不知道有什么方法可以直接这样做。如果您愿意永久断开所有插槽,可以使用disconnect_all_slots()方法。例如:

boost::signal<int ()> foo;
...
foo.disconnect_all_slots();

如果您需要暂时阻止它们,我可以提出的最佳解决方法是使用模拟该行为的自定义组合器。

#include <boost/signals.hpp>
#include <iostream>

//Define a reusable combiner that allows all slots to be blocked
template <typename Combiner>
struct blockable {
   typedef typename Combiner::result_type result_type;

   blockable() : blocked(false), combiner() {}

   //Block or unblock all slots
   void block() {blocked = true;}
   void unblock() {blocked = false;}

   template <typename InputIterator>
   result_type operator()(InputIterator first, InputIterator last) {
      //Either call into inner combiner, or throw if all slots are blocked
      if (!blocked) return combiner(first, last);
      throw std::runtime_error("All slots are blocked");
   }
 private:
   bool blocked;
   Combiner combiner;
};

//Quick and dirty sample using the blockable combiner
int bar() {
   return 1;
}

int main() {
   boost::signal<int (), blockable<boost::last_value<int> > > foo;
   foo.connect(&bar);
   try {
      //show that it works
      int x = foo();
      std::cout << x << std::endl;
      //Now block all slots
      foo.combiner().block();
      int y = foo();
      //This won't run since the last call to foo() should throw
      std::cout << y << std::endl;
   } catch (std::exception& e) {
      //Should get here via 2nd call to foo()
      std::cout << e.what() << std::endl;
   }
   return 0;
}