升压信号如何断开信号?

问题描述 投票:0回答:1

正如boost_offical_web_site所说,boost::function没有可比性。但我对用法有疑问:

#include <boost/signals2.hpp>

class B {
public:
    ~B() {
        printf("B dealloc:%p\n", this);
    }
    void OnSignalActive(void) {
        printf("B get signal address:%p\n", this);
    }
};

void test05() {
    boost::signals2::signal<void (void)> signalConnection;
    B b;
    
    auto v = boost::bind(&B::OnSignalActive, &b);
    auto u = boost::bind(&B::OnSignalActive, &b);
    
//    if (v == u) {//compile error
//
//    }
    
    boost::signals2::slot<void (void)> slot1(v);
    boost::signals2::slot<void (void)> slot2(v);
    
//    if (slot1.slot_function() == slot2) {//compile error
//
//    }
    
    boost::signals2::connection conn = signalConnection.connect(v);
    
    signalConnection();
    
    signalConnection.disconnect(u);
    
    signalConnection();
}

int main(int argc, const char * argv[]) {
    test05();
    return 0;
}

代码signalConnection.disconnect(u)可以断开信号,运行良好。我暂停了boost,按槽进行比较。所以我调试源代码:

void do_disconnect(const T &slot, mpl::bool_<false> /* is_group */)
{
  shared_ptr<invocation_state> local_state =
    get_readable_state();
  typename connection_list_type::iterator it;
  for(it = local_state->connection_bodies().begin();
    it != local_state->connection_bodies().end(); ++it)
  {
    garbage_collecting_lock<connection_body_base> lock(**it);
    if((*it)->nolock_nograb_connected() == false) continue;
    if((*it)->slot().slot_function() == slot)
    {
      (*it)->nolock_disconnect(lock);
    }else
    {
      // check for wrapped extended slot
      bound_extended_slot_function_type *fp;
      fp = (*it)->slot().slot_function().template target<bound_extended_slot_function_type>();
      if(fp && *fp == slot)
      {
        (*it)->nolock_disconnect(lock);
      }
    }
  }
}

发现inner使用==来断开连接,一个是slot_function(actual boost::function),另一个是slot。 但是当我手动创建 boost::signals2::slot 时。无法比较!

/main.cpp:303:31: note: in instantiation of function template specialization 'boost::operator==<boost::signals2::slot<void ()>>' requested here
if (slot1.slot_function() == slot2) {//compile error

我很困惑。

如何能够像这样增强断开连接? 使用槽和槽函数? 为什么手动创建无法比较?

有人可以帮帮我吗!提前3Q。

帮助我并回答问题。

boost signals disconnect
1个回答
0
投票

Boost 不比较函数。它不比较插槽。它比较连接。它们还可以按组名称进行分组。

实际线路是

if((*it)->slot().slot_function().contains(slot))

如果 typeid 匹配,这确实最终会比较函数类型擦除的目标。通过创建您自己的

function_equal
重载以供 ADL 查找,可以为您自己的类型覆盖此行为。

如果绑定表达式可以,Boost 绑定表达式可以进行比较。替换为

std::bind
会导致失败。

这是一个实现,但确实放置了一个存根,例如

friend bool function_equal_impl(auto&&...) { return false; } }

使用 std::bind 进行编译。当然,现在还不能真正比较。

简而言之,除非您的处理程序具有可比性,否则不要使用

disconnect
。如果您有无法比较的处理程序,请使用
scoped_connection
代替:

住在Coliru

#include <boost/signals2.hpp>
namespace signals2 = boost::signals2;

#define TRACE(code) do { printf("%d: %s\n", __LINE__, #code); code; } while (0)

void test05() {
    signals2::signal<void()> signal;

    signals2::scoped_connection v = signal.connect([] { printf("Handler: V\n"); });
    signals2::scoped_connection u = signal.connect([] { printf("Handler: U\n"); });
    TRACE(signal());
    TRACE(v.disconnect());
    TRACE(signal());
}

打印在Coliru上直播

11: signal()
Handler: V
Handler: U
12: v.disconnect()
13: signal()
Handler: U
© www.soinside.com 2019 - 2024. All rights reserved.