2015-12-14 4 views
13

VS2013 अद्यतन 5 में, मैं इस मिल गया है:क्या एक गैर-चलने योग्य, गैर-प्रतिलिपि प्रकार का उदाहरण वापस करना संभव है?

class Lock 
{ 
public: 
    Lock(CriticalSection& cs) : cs_(cs) 
    {} 

    Lock(const Lock&) = delete; 
    Lock(Lock&&) = delete; 
    Lock& operator=(const Lock&) = delete; 
    Lock& operator=(Lock&&) = delete; 

    ~Lock() 
    { 
     LeaveCriticalSection(&(cs_.cs_)); 
    } 

private: 
    CriticalSection& cs_; 
}; 


class CriticalSection 
{ 
    CRITICAL_SECTION cs_; 
public: 
    CriticalSection(const CriticalSection&) = delete; 
    CriticalSection& operator=(const CriticalSection&) = delete; 
    CriticalSection(CriticalSection&&) = delete; 
    CriticalSection& operator=(CriticalSection&&) = delete; 

    CriticalSection() 
    { 
     InitializeCriticalSection(&cs_); 
    } 

    ~CriticalSection() 
    { 
     DeleteCriticalSection(&cs_); 
    } 

    // Usage: auto lock = criticalSection.MakeLock(); 
    Lock MakeLock() 
    { 
     EnterCriticalSection(&cs_); 
     return Lock(*this); 
    } 
} 

MakeLock एक गैर जंगम, गैर copyable प्रकार का एक उदाहरण देता है। और यह ठीक काम करता प्रतीत होता है। लेकिन, विजुअल स्टूडियो इंटेलिजेंस एक चेतावनी के साथ लाल रंग में वापसी को रेखांकित करता है कि लॉक के चालक कन्स्ट्रक्टर को संदर्भित नहीं किया जा सकता क्योंकि यह एक हटाया गया कार्य है।

मैं यह समझने की कोशिश कर रहा हूं कि यह क्यों काम करता है और यदि यह मानक मानक सी ++ या एमएसवीसी के लिए कुछ विशिष्ट है। मुझे लगता है कि रिटर्न काम करता है क्योंकि लौटा मूल्य बनाने की आवश्यकता को अनुकूलित किया जा सकता है, इसलिए इंटेलिजेंस चेतावनी कुछ ऐसी चीज के बारे में चेतावनी देती है जो अभ्यास में नहीं - वास्तव में होती है।

मुझे लगता है कि मैंने कहीं पढ़ा है कि सी ++ यह सुनिश्चित करने के लिए मानकीकृत करेगा कि वापसी मूल्य अनुकूलन हमेशा होता है।

तो, क्या यह अनुरूप कोड ++ कोड है और क्या यह भविष्य के कंपाइलरों में काम करना जारी रखेगा?

पीएस मुझे लगता है कि std::mutex और std::lock_guard इसे प्रतिस्थापित कर सकता है।

+3

मानक सी ++ में कोड खराब हो जाएगा, हालांकि [प्रस्तावित विस्तार] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html) जो कोड को अपेक्षित व्यवहार करेगा। –

+0

ऐसा लगता है कि उस एक्सटेंशन (P0135R0) को मंजूरी दे दी गई है। मुझे लगता है मुझे सी ++ 17 कंपाइलर की प्रतीक्षा करनी है। https://isocpp.org/blog/2015/11/kona- मानक-meeting-trip-report –

+0

नहीं, पी 0135 प्रारंभिक चरणों में और "अनुमोदन" से बहुत दूर है। हालांकि यह बहुत सकारात्मक रूप से प्राप्त प्रतीत होता है, यह अभी तक इसके अंतिम रूप के पास कहीं भी नहीं है। विक्रेता आमतौर पर केवल स्पष्ट दोष रिपोर्ट (अनुमोदन से पहले भी), या वास्तविक कार्य ड्राफ्ट में चीजें जो अंतिम प्रकाशित मानक से आगे जाते हैं, को लागू करते हैं। –

उत्तर

8

यदि यह संकलित करता है, तो यह कंपाइलर में एक बग है। वीसी2015 सही ढंग से संकलित करने में विफल रहता है।

class Foo 
{ 
public: 
    Foo() {} 
    Foo(const Foo&) = delete; 
    Foo(Foo&&) = delete; 
}; 


Foo Bar() 
{ 
    return Foo(); 
} 

मुझे देता है:

xxx.cpp(327): error C2280: 'Foo::Foo(Foo &&)': attempting to reference a deleted function 

और जी ++ 4.9 का कहना है:

error : use of deleted function 'Foo::Foo(Foo&&)' 

मानक बहुत स्पष्ट है कि एक प्रति निर्माता या स्थानांतरित निर्माता मौजूद हैं और सुलभ होनी चाहिए है, भले ही RVO इसका मतलब है कि यह नहीं बुलाया जाता है।

+0

सही। मैंने जांच की है, यहां तक ​​कि g ++ - 5.1 भी इस कोड को संकलित नहीं करता है। परिणाम: 'त्रुटि: हटाए गए फ़ंक्शन का उपयोग' लॉक :: लॉक (लॉक एंड&) ''। – iammilind

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