2014-06-15 21 views
5

std::deque::front() öğesinin bir ilk öğe değerine bir başvuru döndürdüğünü biliyoruz.Bir öğeyi st ++ :: deque öğesinden taşıyın C++ 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 

Ben gcc-4.9 ve eserlerini kullanarak bu kodu denedim ama biz bu kod güvenli düşünün eğer bilmiyorum: Bu kod her zaman güvenli olup olmadığını isterim bilmek!

+1

Neredeyse geçerli bir koddur. Neredeyse - çünkü boşluğu kontrol etmiyorsun. Depolanan elemanın hareketi güvenli bir işlemdir. – bobah

+0

Yazım hatası raporu: 'kilitle ''' '' '' '' '' '' '' '' '' '' '' '' ' – Notinlist

cevap

8

Taşıyıcıyı std::function taşıyıcısına taşıyın istisna atmadığından emin olun, bu nedenle özel bir güvenlik sorununuz var. m için RAII kilidi kullanmadığınız için, auto f = move(funs.front()); atarsa ​​kilitli kalır. Sen std::unique_lock ile sorunu düzeltebilirsiniz:

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 
} 

veya 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

Merhaba Casey, muhtemelen (şimdilik) en iyi çözüm birincisidir, çünkü ikinci durumda lamblar yığın halinde saklanır ve performans sebebi otomatik olarak kullanmak için daha iyi olabilir –

+2

@GianLorenzoMeocci Neden daha iyi performans vermeli? İlk snippet'teki auto f', decltype (move (funs.front())) f' ile aynı olacaktır. Yani decltype (move (funs.front())) f sn ile bildirerek ikinci snippet'te aynı şeyi verecektir. – Walter

+0

Otomatik kullanmanız nedeniyle lambdaları yığın halinde saklayacaksınız –