簡體   English   中英

使用成員函數移動std :: function

[英]Moving std::function with member function

我已經使用std::function編寫了一個超級簡單的事件系統。

等於

std::vector<Delegate<Args ...>*> _delegates;

其中Delegatestd::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 ...並留出了很大的出錯空間。

我喜歡這些事件的簡單性(盡管我樂於接受建議),但是我真正想要的是一種保持該事件系統並簡化動作的方法。

有什么建議么?

謝謝

在我看來,您沒有正確使用移動分配,除了創建副本之外,您沒有移動任何東西。 event_receiver是從頭開始創建的,不會移動。

我知道寫一個移動函數的想法很誘人,因為它會自動提高效率。 但是,在編寫此類功能時,可以通過有效地移動對象成員來獲得效率。

在您的情況下,我認為您可以簡單地使用副本分配並讓dtor取消注冊,或更改move函數以移動對象成員。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM