2014-06-15 11 views
5

में std :: deque से तत्व को ले जाएं हम जानते हैं कि std::deque::front() डेक के पहले तत्व का संदर्भ देता है। इस कोड को हमेशा सुरक्षित है अगर मैं करूंगा पता करने के लिए:सी ++ 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 

मैं का उपयोग कर जीसीसी-4.9 और काम करता है इस कोड की कोशिश की है, लेकिन मैं अगर हम इस कोड सुरक्षित विचार कर सकते हैं पता नहीं है!

+1

यह लगभग एक मान्य कोड है। लगभग - क्योंकि आप खालीपन की जांच नहीं कर रहे हैं। संग्रहीत तत्व की गति एक सुरक्षित संचालन है। – bobah

+0

टाइपो रिपोर्ट: आप 'm'' पर 'लॉक() 'और' अनलॉक()' 'm_' पर उपयोग करते हैं। – 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

हाय केसी, शायद (अभी के लिए) सबसे अच्छा समाधान पहला है क्योंकि दूसरे मामले में लैम्ब्डा ढेर में जमा हो जाएगा और प्रदर्शन कारण के लिए ऑटो –

+2

@GianLorenzoMeocci का उपयोग करना बेहतर हो सकता है क्यों 'ऑटो' बेहतर प्रदर्शन देना चाहिए? पहले स्निपेट में 'ऑटो एफ' 'decltype (move (funs.front())) f' के समान होगा। तो 'स्निपेट (मूव (funs.front())) घोषित करके दूसरे स्निपेट में f' वही देगा। – Walter

+0

क्योंकि ऑटो का उपयोग करके आप लैम्बडा को ढेर में स्टोर करेंगे –