我正在使用boost库,我的问题是关于boost :: signals
我有一个信号可能会调用许多不同的插槽,但只有一个插槽与呼叫匹配,因此我希望此特定插槽返回true并且呼叫将停止。
有可能吗?
有效吗?
如果效率不高,你们可以建议我更好的方法吗?
答案 0 :(得分:6)
经过一些研究,我发现在提升文档中他们写的是Slots that return values 他们建议使用这样的不同组合器:
struct breakIfTrue
{
template<typename InputIterator>
bool operator()(InputIterator first, InputIterator last) const
{
if (first == last)
return false;
while (first != last) {
if (*first)
return true;
++first;
}
}
};
boost::signal<bool(), breakIfTrue> sig;
现在为什么这是错误的做法?
答案 1 :(得分:3)
尽管有可能,但它肯定与信号的“通用发布/订阅”意图相反。槽。
我认为你真正想要的是Chain of Responsibility设计模式。
答案 2 :(得分:2)
正如德鲁所说,这听起来不适合信号和插槽。
正如dribeas所说,解决方法是一个带有bool& found
参数的协议,该参数以false开头,每个插槽在开始时检查,如果真的则返回。如果任何插槽将值设置为true,则其他调用的处理将很快发生。
但是为了覆盖所有基础(即使是不可取的),我会提到由于boost :: signal是all run on the same thread as the caller,你可以从信号中抛出自定义异常,然后在呼叫站点捕获它。无论好坏,当人们觉得他们没有其他选择时,人们偶尔会诉诸于此...就像在提升图库中的访问者算法中一样:
How do I stop the breadth-first search using Boost Graph Library when using a custom visitor?
现在我已经提到了,不要这样做。 :)
更新:不知道但是你发现boost有一种机制可以使用迭代器而不是结果值的组合器优雅地处理它:
“传递给组合器的输入迭代器将解除引用操作转换为槽调用。因此,组合器可以选择仅调用某些槽,直到满足某个特定条件。”
如果你确定自己坚持使用提升,那么你已经回答了自己的问题,因为这样做符合你的要求。虽然请注意其他信号/插槽系统(如Qt)不会与此平行......