使用成员函数移动std :: function

时间:2015-08-30 06:01:16

标签: c++ c++11 std move std-function

我使用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 ...并留下很大的错误空间。

我喜欢这些事件的简单性(虽然我愿意接受建议),但我真正想要的是保持这个事件系统并简化移动的方法。

有什么建议吗?

由于

1 个答案:

答案 0 :(得分:-1)

在我看来,你似乎没有正确使用移动任务,除了创建副本之外,你不能移动任何东西。 event_receiver是从头开始创建的,不会移动。

我知道写一个移动函数很有诱惑力,认为它会自动提高效率。 但是在编写这样的函数时,可以通过有效地移动对象成员来获得效率。

在您的情况下,我认为您可以简单地使用复制作业并让dtor进行取消注册,或者更改移动功能以移动对象成员。