2017-06-13 75 views
2

我在想,如果下面的代碼是安全的使用,如果沒有,是否有可能使其安全?移動會不會跟蹤參考?

{ 
    ThreadState state = ThreadState::Running; 
    auto pair = std::make_pair(std::async([&state]() 
    { 
     state = ThreadState::Waiting; 
    }), std::move(state)); 
    someVector.emplace(std::move(pair)); 
} 

執行std::move之後,lambda會記錄正確的參考嗎?國家的壽命會延長嗎?我可以改進它來創建一對lambda及其捕獲狀態嗎?

+0

這些是枚舉?你想做什麼?也許有更好的辦法? – Nim

+0

@Nim這是我正在做的一個最簡單的例子。有沒有更好的辦法? https://pastebin.com/embed_js/9DKguWeK –

+0

這看起來不正確,例如,如果在進行測試時沒有任何異步任務在內部循環中完成,那麼外部循環會再次運行,並且計劃更多任務 - 理論上你可以有比你需要的批量大小更多的任務。在啓動任務的內部循環下面,你應該等待所有的任務完成。這保證了最多隻能運行你的線程數需要.. – Nim

回答

2

將拉姆達跟蹤執行的std ::移動後的正確參考的?

不,lambda將引用移動從state,現在將有一個不確定的值。

請問態的壽命延長?

state的生存期在封閉範圍結束時結束。的狀態的內部std::pair的壽命中,向其中在移動的state值,當然由的壽命來確定std::vector你佈設/推入。

我可以改進它來創建一對lambda及其捕獲狀態嗎?

一個解決方案,雖然它使用的是動態存儲,是使用std::unique_ptr

{ 
    auto state = std::make_unique<ThreadState>(ThreadState::Running); 
    vec.emplace_back(
    std::async([s = state.get()]() 
    { 
     *s = ThreadState::Waiting; 
    }), 
    std::move(state) 
); 
} 
+0

我應該那麼首先創建一個對一個空的λ和交換拉姆達出來,從對的第二個元素捕捉? –

+1

@AdamHunyadi:這可能不起作用,因爲當你將'std :: pair'移動/複製到'std :: vector'(或者當該矢量調整大小)時,你的'ThreadState'也會移動,使參考。 – You

+1

@You如果您只更新拉姆達,這應該工作,例如'vec.back()。first = [state =&vec.back()。second](){}',但當然這不會成立,如果矢量調整大小等,但可能會有更好的設計這是OP想要做的。 – Holt