2014-09-24 14 views
27

पुस्तक "कार्रवाई में सी ++ कन्करेंसी" में लौटने पढ़ने के लिए निम्न विधिसी ++ 11 कदम जब एक ताला

std::unique_lock<std::mutex> wait_for_data() 
{ 
    std::unique_lock<std::mutex> head_lock(head_mutex); 
    data_cond.wait(head_lock,[&]{return head.get()!=get_tail();}); 
    return std::move(head_lock); 
} 

मैं नहीं समझ सकता क्यों head_lock std :: चाल-एड जब वापस लौटा है। चाल के उपयोग और आरवीओ की मेरी धारणा और आंत महसूस C++11 rvalues and move semantics confusion (return statement)

पर साझा राय से मेल खाता है लेकिन मैं लेखक को बेहतर तरीके से जानने के लिए भरोसा करता हूं। क्या कोई स्पष्टीकरण दे सकता है जब std :: वापसी मूल्य को स्थानांतरित करना बेहतर होता है और क्या ताले के बारे में कुछ खास है? धन्यवाद।

उत्तर

25

यह std::move के साथ या उसके बिना ठीक है। स्थानीय चर * का नाम return कथन में एक रैवल्यू के रूप में माना जाता है, जिससे दोनों मामलों में चालक कन्स्ट्रक्टर को बुलाया जा सकता है। स्टाइलिस्ट कारणों से लेखकों ने संभावित रूप से std::move का उपयोग किया, यह स्पष्ट करने के लिए कि लॉक को स्थानांतरित किया जा रहा है। यह एनआरवीओ में हस्तक्षेप करता है, लेकिन unique_lock को स्थानांतरित करने की लागत लॉक और प्रतीक्षा की लागत की तुलना में शायद न्यूनतम है।

@ डेडुप्लिकेटर के शब्दों में, यह "वास्तविक अर्थशास्त्र पर जोर देने के लिए एक निराशा" है।

आप इसे स्वयं जांच सकते हैं - unique_lock कॉपी नहीं किया जा सकता है, इसलिए return head_lock; संकलित नहीं किया गया था अगर यह एक प्रतिलिपि थी।


* यह सी ++ 14 नियम है। सी ++ 11 नियम restricted to cases where copy elision is allowed or would be allowed except for the fact that the variable is a function parameter है। जहां तक ​​इस सवाल का सवाल है, यह अंतर असीमित है, क्योंकि head_lock स्पष्ट रूप से प्रतिलिपि elision के लिए अर्हता प्राप्त करता है।

+1

मैंने इसे बिना किसी बदलाव के संकलित करने की कोशिश की, और g ++ वास्तव में इसे संकलित करता है। –

+0

की प्रतिलिपि नहीं बनाई जा सकती है, लेकिन इसे चलाया जा सकता है! तुम गलत हो ! –

+1

@typical बिल्कुल, क्योंकि यह एक कदम है, एक प्रति नहीं, यहां तक ​​कि 'std :: move' के बिना भी। –