2014-06-15 76 views
5

我們知道std::deque::front()返回對deque的第一個元素的引用。 我想知道,如果這個代碼始終是安全的:在C++中移動std :: deque中的元素11

//deque of lambdas 
deque<function<void(void)>> funs; 

// then is some other place: 
// take a lock 
m.lock(); 
auto f = move(funs.front()); // move the first lambda in f 
funs.pop_front(); // remove the element from deque //now the value is hold by f 
m_.unlock(); // unlock the resorce 
f(); //execute f 

我用gcc-4.9和作品嚐試這種代碼,但我不知道我們是否可以考慮這個代碼安全!

+1

這幾乎是一個有效的代碼。幾乎 - 因爲你沒有檢查空虛。存儲的元素的移動是安全操作。 – bobah

+0

錯字報告:在'm'上使用'lock()',在'm_'上使用'unlock()'。 – Notinlist

回答

8

std::function移動構造函數不保證不拋出異常,所以你有一個異常安全問題。由於您沒有使用m的RAII鎖,因此如果auto f = move(funs.front());引發,它將保持鎖定狀態。你可以用std::unique_lock糾正問題:

std::unique_lock<decltype(m)> lock{m}; 
if (!funs.empty()) { 
    auto f = move(funs.front()); // move the first lambda in f 
    funs.pop_front(); // remove the element from deque //now the value is hold by f 
    lock.unlock(); // unlock the resorce 
    f(); //execute f 
} 

std::lock_guard

function<void()> f; 
{ 
    std::lock_guard<decltype(m)> lock{m}; 
    if (!funs.empty()) { 
    f = move(funs.front()); // move the first lambda in f 
    funs.pop_front(); // remove the element from deque //now the value is hold by f 
    } 
} 
if (f) f(); //execute f 
+0

嗨凱西,可能(現在)最好的解決方案是第一個,因爲在第二種情況下,lambda將存儲到堆中,併爲性能的原因可能會更好地使用自動 –

+2

@GianLorenzoMeocci爲什麼要'自動'提供更好的性能?第一個片段中的'auto f'將與'decltype(move(funs.front()))f'相同。所以通過在第二個片段中聲明'decltype(move(funs.front()))f'將會給出相同的結果。 – Walter

+0

,因爲使用auto會將lambda存儲在堆棧中 –

相關問題