如果其中一个返回 true,有没有办法阻止 boost::signal 调用其插槽?

发布于 2024-08-16 11:59:23 字数 155 浏览 10 评论 0原文

我正在使用 boost 库,我的问题是关于 boost::signals 的。
我有一个信号可能会调用许多不同的插槽,但只有一个插槽与调用匹配,因此我希望该特定插槽返回 true 并且调用将停止。
可能吗?
效率高吗?
如果效率不高,你们能建议我一个更好的方法吗?

I am using the boost library and my question is about boost::signals.
I have a signal that might call many different slots but only one slot will match the call so I want this particular slot to return true and that the calling will stop.
Is it possible?
Is it efficient?
Can you guys suggest me a better way to do it if it's not efficient?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

霓裳挽歌倾城醉 2024-08-23 11:59:24

经过一些研究,我发现在 boost 文档中他们写了 返回值的槽
他们建议使用不同的组合器,如下所示:

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;

现在为什么这样做是错误的?

After some research I've found that in boost documentation they write about Slots that return values.
They suggest to use a different combiner like this:

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;

Now why is that the wrong thing to do?

囍笑 2024-08-23 11:59:24

虽然这可能是可能的,但这肯定与信号和信号的“通用发布/订阅”意图相反。插槽。

我认为您真正寻找的是 责任链 设计模式。

While it may be possible, it's certainly contrary to the "generic publish/subscribe" intent of signals & slots.

I think what you're really looking for is the Chain of Responsibility design pattern.

陪我终i 2024-08-23 11:59:24

正如德鲁所说,这听起来并不适合信号和槽。

正如dribeas所说,解决方法是使用带有bool&的协议。 find 参数从 false 开始,每个槽在开始时进行检查,如果为 true,则返回。如果任何插槽将该值设置为 true,则其他调用的处理将会非常快地发生。

但为了涵盖所有基础(甚至是不建议的基础),我会提到,因为 boost::signals 是 全部与调用者在同一线程上运行,您可以从信号中抛出自定义异常,然后在以下位置捕获它呼叫站点。无论好坏,当人们觉得自己别无选择时,他们偶尔会诉诸于此……就像在 boost 图库中的访问者算法中一样:

使用自定义访问者时,如何停止使用 Boost Graph Library 进行广度优先搜索?

既然我已经提到了,请不要这样做。 :)

更新: 不知道,但你发现 boost 有一种机制可以通过采用迭代器而不是结果值的组合器来优雅地处理这个问题:

“因此,传递给组合器的输入迭代器将解引用操作转换为槽调用,因此组合器可以选择仅调用某些槽,直到满足某些特定条件。"

如果您确定自己坚持使用 boost,那么您就已经回答了自己的问题,因为这就是您想要的。不过请注意,其他信号/槽系统(例如 Qt 的)不会与此类似......

As Drew says, this doesn't sound befitting of signals and slots.

And as dribeas says, a workaround is a protocol with a bool& found parameter that starts out false, with every slot checking at the start and returns if its true. If any slot sets the value to true, then processing of the other calls will happen very quickly.

But just to cover all the bases (even the inadvisable ones), I'll mention that since boost::signals are all run on the same thread as the caller you could throw a custom exception from within the signal, then catch it at the call site. For better or worse, people occasionally resort to this when they feel they have no other option...like during visitor algorithms in the boost graph library:

How do I stop the breadth-first search using Boost Graph Library when using a custom visitor?

And now that I've mentioned it, don't do it that way. :)

UPDATE: Didn't know it but you found that boost has a mechanism for handling this elegantly with combiners that take iterators and not result values:

"The input iterators passed to the combiner transform dereference operations into slot calls. Combiners therefore have the option to invoke only some slots until some particular criterion is met."

If you're sure you're sticking with boost then you've answered your own question because that does what you want. Though do note that other signal/slot systems (like Qt's) won't have a parallel to this...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文