2014-06-15 8 views
5

Sappiamo che std::deque::front() restituisce un riferimento a un primo elemento di deque. vorrei sapere se questo codice è sempre sicuro:Spostare un elemento da std :: deque in 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 

Ho provato questo codice usando gcc-4.9 e le opere, ma non so se possiamo considerare questo codice di sicurezza!

+1

E 'quasi un codice valido. Quasi - perché non stai controllando il vuoto. Lo spostamento dell'elemento memorizzato è un'operazione sicura. – bobah

+0

Rapporto typo: si usa 'lock()' su 'm' e' unlock() 'su' m_'. – Notinlist

risposta

8

Il costruttore di spostamenti std::function non è garantito per non generare eccezioni, quindi è presente un problema di sicurezza delle eccezioni. Dato che non stai utilizzando un blocco RAII per m, rimarrà bloccato se auto f = move(funs.front()); genera. È possibile correggere il problema con 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 
} 

o 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

Ciao Casey, probabilmente (per ora) la soluzione migliore è la prima perché nel secondo caso il lambdas verrà archiviato in heap e per motivi di prestazioni potrebbe essere meglio utilizzare l'auto –

+2

@GianLorenzoMeocci Perché "auto" dovrebbe fornire prestazioni migliori? 'auto f' nel primo snippet sarà identico a' decltype (move (funs.front())) f'. Quindi dichiarando 'decltype (move (funs.front())) f' nel secondo snippet darà lo stesso. – Walter

+0

perché usando auto memorizzerai i lambda in pila –

Problemi correlati