我使用std::function
编写了一个超级简单的事件系统。
相当于
std::vector<Delegate<Args ...>*> _delegates;
Delegate
的别名为std::function
template <typename ... Args>
using Delegate = std::function<void(Args ...)>;
事件的operator()
,operator+=
和operator-=
已超载。
operator() calls all of the listening functions.
operator+= adds a listener.
operator-= removes a listener.
将它们挂起来就像这样......
Foo::Foo(Bar& bar)
{
...
m_bar_ptr = &bar;
using namespace std::placeholders;
event_receiver =
Delegate<const Bar&, const SomeBarData>
(std::bind(&Foo::OnEventReceived, this, _1, _2));
bar.BarEvent += event_receiver;
...
}
一切都按预期工作,但当我移动Delegate
的所有者时,我最终不得不解开并复制初始连接的代码(如预期的那样)。
看起来像这样......
Foo& Foo::operator=(Foo&& other)
{
...
m_bar_ptr = other.m_bar_ptr;
other.m_bar_ptr = nullptr;
m_bar_ptr->BarEvent -= other.event_receiver;
using namespace std::place_holders;
event_receiver =
Delegate<const Bar&, const SomeBarData>
(std::bind(&Foo::OnEventReceived, this, _1, _2));
bar.BarEvent += event_receiver;
...
}
除了必须保留Bar的句柄,这是可以接受的,这是很多代码重新定位Delegate
...并留下很大的错误空间。
我喜欢这些事件的简单性(虽然我愿意接受建议),但我真正想要的是保持这个事件系统并简化移动的方法。
有什么建议吗?
由于
答案 0 :(得分:-1)
在我看来,你似乎没有正确使用移动任务,除了创建副本之外,你不能移动任何东西。 event_receiver是从头开始创建的,不会移动。
我知道写一个移动函数很有诱惑力,认为它会自动提高效率。 但是在编写这样的函数时,可以通过有效地移动对象成员来获得效率。
在您的情况下,我认为您可以简单地使用复制作业并让dtor进行取消注册,或者更改移动功能以移动对象成员。