我正在使用 boost 库,我的问题是关于 boost::signals。
我有一个信号可能会调用许多不同的插槽,但只有一个插槽会匹配调用,所以我希望这个特定的插槽返回 true 并且调用将停止。
是否可以?
它有效率吗?
如果效率不高,你们能建议我更好的方法吗?
3 回答
经过一些研究,我发现在 boost 文档中,他们写了关于返回值的 Slots。
他们建议使用不同的组合器,如下所示:
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;
现在为什么这是错误的做法?
虽然这可能是可能的,但它肯定与信号和插槽的“通用发布/订阅”意图相反。
我认为您真正在寻找的是责任链设计模式。
正如 Drew 所说,这听起来不适合信号和插槽。
正如 dribeas 所说,一种解决方法是一个协议,它的bool& found
参数以 false 开头,每个插槽都在开始时检查,如果为 true,则返回。如果任何插槽将该值设置为 true,则其他调用的处理将很快发生。
但只是为了涵盖所有基础(甚至是不建议的基础),我会提到,由于 boost::signals 都在与调用者相同的线程上运行,您可以从信号中抛出自定义异常,然后在呼叫站点。无论好坏,人们偶尔会在他们觉得别无选择时诉诸于此……例如在 boost 图形库中的访问者算法中:
使用自定义访问者时,如何使用 Boost Graph Library 停止广度优先搜索?
现在我已经提到了,不要那样做。:)
更新:不知道,但你发现 boost 有一种机制可以优雅地处理这个问题,组合器采用迭代器而不是结果值:
“传递给组合器的输入迭代器将取消引用操作转换为槽调用。因此,组合器可以选择仅调用一些槽,直到满足某些特定条件。”
如果您确定要坚持使用 boost,那么您已经回答了自己的问题,因为那可以满足您的要求。虽然请注意其他信号/插槽系统(如 Qt 的)不会与此平行......