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

C++ 使用成员函数移动std::function,c++,c++11,std,move,std-function,C++,C++11,Std,Move,Std Function,我已经使用std::function编写了一个超级简单的事件系统 这相当于 std::vector<Delegate<Args ...>*> _delegates; 使用事件的运算符、运算符+=、运算符-=重载 operator() calls all of the listening functions. operator+= adds a listener. operator-= removes a listener. 把它们连接起来看起来像这样 Foo::Foo

我已经使用std::function编写了一个超级简单的事件系统

这相当于

std::vector<Delegate<Args ...>*> _delegates;
使用事件的运算符、运算符+=、运算符-=重载

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;

    ...
}
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句柄(这是可以接受的)之外,这需要大量代码来重新定位委托……并为错误留下很大的空间

我喜欢这些活动的简单性,尽管我愿意接受建议,但我真正想要的是保持活动系统和简化动作的方法

有什么建议吗


谢谢

在我看来,您似乎没有正确使用移动分配,除了创建副本,您没有移动任何东西。 事件接收器是从头创建的,不会移动

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


在您的情况下,我认为您可以简单地使用一个复制赋值,让dtor进行注销,或者更改move函数来移动对象成员。

为什么要使用std::function的原始指针向量?因为std::functions无法进行相等性比较。我将它们存储在std::vector中,需要能够找到它们以便删除,并避免添加重复项。在这种情况下,在移动过程中,Foo只创建了一个非常轻的新委托,只是一个std::函数,但Foo本身可能是一个大对象,可以从移动中受益。
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;

    ...
}