2017-08-29 36 views
7

मैं निम्नलिखित सी है ++ (11) कोड:std :: unique_lock पर std :: move क्यों नहीं है इसका कोई प्रभाव पड़ता है?

#include <mutex> 

void unlock(std::unique_lock<std::mutex> && ulock) 
{ 
} 

int main(void) 
{ 
    std::mutex m; 
    std::unique_lock<std::mutex> ulock(m); 

    unlock(std::move(ulock)); 

    if (ulock.mutex() == &m || ulock.owns_lock()) 
    { 
     throw std::runtime_error(""); 
    } 

    return 0; 
} 

क्या मैं समझ नहीं है क्यों म्युटेक्स अभी भी unlock() से लौटने के बाद आयोजित किया जाता है। मेरी उम्मीद यह है कि std::move() कॉल से unlock() पर लौटने पर लॉक को दायरे से बाहर जाने और विनाशक द्वारा अनलॉक कर दिया जाता है। कम से कम, ऐसा लगता है कि std::move()ulock को mutex m से "अनबाउंड" बनने के कारण होना चाहिए था।

मुझे क्या याद आ रही है?

+7

'std :: move' खुद को कहीं भी कहीं भी स्थानांतरित नहीं करता है। यह बस एक रैवल्यू संदर्भ के लिए एक लाभा का कारण बनता है, जिससे यह चालक रचनाकारों और इस तरह के तर्क की अनुमति देता है। जो बदले में अस्थायी हैं (वे क्या सोचते हैं) के आंतरिक चोरी कर सकते हैं। लेकिन आपका कोड उनमें से किसी को भी कॉल नहीं करता है। 'अनलॉक (std :: move (ulock));' एक विस्तृत नो-ऑप है। –

+0

मूल्य से 'std :: unique_lock' लेने के लिए 'अनलॉक' को परिभाषित करें, फिर – WhiZTiM

+3

प्रभाव देखने के लिए इसमें जाएं, मैंने सोचा था कि std :: move() ने अद्वितीय_लॉक के लिए चालक कन्स्ट्रक्टर को बुलाया था। ऐसा लगता है कि यह मामला नहीं है ... बल्कि, 'अनलॉक()' में रावल संदर्भ एक प्रकार का "अधिसूचना" है जो * * * चालक कन्स्ट्रक्टर का उपयोग कर सकता है, इसलिए इसे चुनना चाहिए (यदि यह समझ में आता है)। –

उत्तर

12
void unlock(std::unique_lock<std::mutex> && ulock) 

यहाँ ulock एक संदर्भ है। एक विशेष प्रकार का संदर्भ, लेकिन अभी भी एक संदर्भ। यह एक और वस्तु के लिए सिर्फ एक उपनाम है। इसकी रचना में एक नई वस्तु, या किसी भी प्रकार के स्वामित्व हस्तांतरण का निर्माण शामिल नहीं है। इसी तरह, अपने जीवनकाल का अंत किसी भी विनाशक कॉल का कारण नहीं बनता है, इसका मतलब यह है कि आपने किसी अन्य वस्तु का जिक्र करने के लिए उपनाम खो दिया है (यह महत्वपूर्ण नहीं है, क्योंकि फ़ंक्शन किसी भी तरह समाप्त हो रहा है)।

आप स्वामित्व स्थानांतरित करना चाहते हैं, तो आप एक वस्तु आवश्यकता है, तो मूल्य के बजाय संदर्भ द्वारा पारित:

void unlock(std::unique_lock<std::mutex> ulock) 

अब, आप move मूल ताला करना होगा, std::unique_lock के बाद से समर्थन नहीं करता है निर्माण की प्रतिलिपि बनाएँ, केवल निर्माण को स्थानांतरित करें।

संबंधित मुद्दे