从回调中删除调用信号 boost::signals c++
Deleting calling signal from callback boost::signals c++
我有以下代码在信号回调之一期间删除信号:
#include <iostream>
#include <boost/signals2/signal.hpp>
struct Foo {
boost::signals2::signal<void(int)> signal;
};
std::vector<Foo> foos;
foos.emplace_back(Foo());
std::vector<int> values;
auto connection = boost::signals2::scoped_connection(foos[0].signal.connect([&](int x) {
foos.clear(); // delete the foos here, where we will be calling from below
values.emplace_back(1);
}));
foos[0].signal(1);
std::cout << "values.size()=" << values.size() << "\n";
我只是在这个“工作”中很幸运(因为它是未定义的行为)还是在 signals2 中有一些魔法指针在阻止我吹走我的脚?
// delete the foos here, where we will be calling from below
这是误导性评论。删除 (clear()
) 仅在 发出信号后 发生,因此控制流与代码行的顺序相反。
对我来说,这段代码看起来有效,除非你从信号处理程序中破坏 connection
(例如 connection.release();
)。即使这样,它 也可能 是安全的,但这取决于处理程序迭代的实现细节。我怀疑它仍然没问题,因为 Signals2 库是明确的线程感知的,所以反过来一定没问题(在信号调用期间将处理程序添加到同一个槽)。
is there some magic pointer counting in signals2 that is stopping me from blowing my feet off?
Signals2 中神奇的引用计数是您已经拥有的位:scoped_connection
,当最后一个副本超出范围时,它将自动断开连接。
Not really related to the code shown:
You can of course have the same facility on your own entities, by using things std::vector<shared_ptr<Foo> >
. If the references/iterators to elements of foos
need to be stable, use std::list
or std::deque
(with only front/back insertion/removals).
这是我对通过 UBsan/ASan 优化和未优化的代码的看法:
#include <boost/signals2/signal.hpp>
#include <iostream>
namespace s2 = boost::signals2;
struct Foo {
s2::signal<void(int)> onEvent;
};
int main() {
std::vector<Foo> foos(3);
std::vector<int> values;
std::cout << "before values.size()=" << values.size() << "\n";
s2::scoped_connection connection =
foos.back().onEvent.connect([&](int x) {
foos.clear(); // delete the foos here
values.emplace_back(1);
connection.release();
});
foos.back().onEvent(1);
std::cout << "after values.size()=" << values.size() << "\n";
}
版画
before values.size()=0
after values.size()=1
我有以下代码在信号回调之一期间删除信号:
#include <iostream>
#include <boost/signals2/signal.hpp>
struct Foo {
boost::signals2::signal<void(int)> signal;
};
std::vector<Foo> foos;
foos.emplace_back(Foo());
std::vector<int> values;
auto connection = boost::signals2::scoped_connection(foos[0].signal.connect([&](int x) {
foos.clear(); // delete the foos here, where we will be calling from below
values.emplace_back(1);
}));
foos[0].signal(1);
std::cout << "values.size()=" << values.size() << "\n";
我只是在这个“工作”中很幸运(因为它是未定义的行为)还是在 signals2 中有一些魔法指针在阻止我吹走我的脚?
// delete the foos here, where we will be calling from below
这是误导性评论。删除 (clear()
) 仅在 发出信号后 发生,因此控制流与代码行的顺序相反。
对我来说,这段代码看起来有效,除非你从信号处理程序中破坏 connection
(例如 connection.release();
)。即使这样,它 也可能 是安全的,但这取决于处理程序迭代的实现细节。我怀疑它仍然没问题,因为 Signals2 库是明确的线程感知的,所以反过来一定没问题(在信号调用期间将处理程序添加到同一个槽)。
is there some magic pointer counting in signals2 that is stopping me from blowing my feet off?
Signals2 中神奇的引用计数是您已经拥有的位:scoped_connection
,当最后一个副本超出范围时,它将自动断开连接。
Not really related to the code shown:
You can of course have the same facility on your own entities, by using things
std::vector<shared_ptr<Foo> >
. If the references/iterators to elements offoos
need to be stable, usestd::list
orstd::deque
(with only front/back insertion/removals).
这是我对通过 UBsan/ASan 优化和未优化的代码的看法:
#include <boost/signals2/signal.hpp>
#include <iostream>
namespace s2 = boost::signals2;
struct Foo {
s2::signal<void(int)> onEvent;
};
int main() {
std::vector<Foo> foos(3);
std::vector<int> values;
std::cout << "before values.size()=" << values.size() << "\n";
s2::scoped_connection connection =
foos.back().onEvent.connect([&](int x) {
foos.clear(); // delete the foos here
values.emplace_back(1);
connection.release();
});
foos.back().onEvent(1);
std::cout << "after values.size()=" << values.size() << "\n";
}
版画
before values.size()=0
after values.size()=1