正如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 不比较函数。它不比较插槽。它比较连接。它们还可以按组名称进行分组。
实际线路是
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
代替:
#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());
}
11: signal()
Handler: V
Handler: U
12: v.disconnect()
13: signal()
Handler: U