2011-05-19 12 views
6

सामान्य गलती के साथ "स्कॉप्ड लॉक" मुहावरे का उदाहरण यहां दिया गया है: कोई स्थानीय चर नहीं बनाया गया है, इसलिए लॉक प्रभावी नहीं है। इस कोड को दोषरहित दोनों संकलित कुलपति ++ 2010 और Comeau सी के साथ ++ ऑनलाइन:अस्थायी उदाहरणों के साथ कॉन्स्ट शुद्धता

error C2512: 'ScopedLock' : no appropriate default constructor available

(जब ScopedLock सही तरीके से उपयोग, अर्थात्:

ScopedLock के लिए डिफ़ॉल्ट निर्माता बाहर टिप्पणी की है, तो दोनों compilers एक त्रुटि देना स्थानीय चर बनाई गई है: ScopedLock guard(m_mutex);, तो संकलन के रूप में उम्मीद m_mutex के रूप में अस्थायी फिक्स समस्या)

की घोषणा में विफल रहता है मैं दो प्रश्न हैं:।।

+०१२३५१६४१०
  1. क्यों X::foo संकलित करता है? ऐसा लगता है कि कंपाइलर const Mutex& को Mutex& किसी भी तरह से डालने में सक्षम था।

  2. क्या भूमिका ScopedLock डिफ़ॉल्ट कन्स्ट्रक्टर निभाती है, तो संकलन सफल होता है?

धन्यवाद।

अद्यतन: मुझे जवाब मिला। ऐसा लगता है कि ScopedLock(m_mutex); कथन ScopedLock प्रकार के स्थानीय चर m_mutex बनाता है। अस्थायी नहीं यही कारण है कि ScopedLock::ScopedLock डिफ़ॉल्ट कन्स्ट्रक्टर की आवश्यकता है।

उत्तर

4

आपने स्वयं से सवाल का जवाब दिया।

It appears that ScopedLock(m_mutex); statement creates a local variable m_mutex of type ScopedLock

स्पष्टीकरण मानक की धारा 6 में पाया जाना है।8 अस्पष्टता संकल्प:

There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion [5.2.3] as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.

स्टैंडर्ड तो एक बयान वास्तव में एक घोषणा है कि का एक उदाहरण के रूप में T(a); सूचीबद्ध करता है। यह T a;

के समतुल्य है यह कुख्यात सी ++ "सबसे परेशान पार्स" का एक भिन्नता है।

+0

मानक से उत्तर और प्रासंगिक उद्धरण के लिए धन्यवाद। –

1

मैं यकीन है कि आपकी समस्या लाइन 26 है कर रहा हूँ: ScopedLock(m_mutex);

इसके बजाय, ऐसा ही कुछ ScopedLock a_variable_name(m_mutex);

जब मैं यह बदलाव लाना, मैं उम्मीद त्रुटियों प्राप्त होना चाहिए:

constCorrectness.cpp: In member function ‘void X::foo() const’: 
constCorrectness.cpp:26: error: no matching function for call to ‘ScopedLock::ScopedLock(const Mutex&)’ 
constCorrectness.cpp:18: note: candidates are: ScopedLock::ScopedLock(const ScopedLock&) 
constCorrectness.cpp:11: note:     ScopedLock::ScopedLock(Mutex&) 
constCorrectness.cpp:10: note:     ScopedLock::ScopedLock() 

शायद कोई हमारे लिए ScopedLock(m_mutex) व्याख्या कर सकता है? क्या यह एक समारोह या कुछ घोषित करता है? प्रश्नकर्ता द्वारा अपेक्षित कन्स्ट्रक्टर को कॉल करने के बजाय? अद्यतन: इसे बाहर निकालना। मुझे लगता है कि यह सिर्फ एक परिवर्तनीय घोषणा है (यानी ब्रैकेट को नजरअंदाज कर दिया जाता है।)

+1

मेरे अपने उत्तर के अंत में छोड़े गए प्रश्न पर टिप्पणी करते हुए: मुझे लगता है कि आपकी लाइन 26 बस एक और परिवर्तनीय घोषित करती है, जो एक्स :: फू के लिए स्थानीय है, जिसे 'm_mutex' भी कहा जाता है। ब्रैकेट मूल रूप से अनदेखा कर रहे हैं। यही कारण है कि यह डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग करता है। –

+0

@ aaron-mcdaid, हाँ, आप सही हैं। बस इसे खुद की खोज की। 'ScopedLock' प्रकार का स्थानीय चर बनाया गया था। –

+0

यह अच्छा है। मैंने पहले कभी इस मुहावरे के बारे में कभी नहीं सुना होगा, इसलिए एक दिलचस्प सवाल के लिए धन्यवाद। –

0

समस्या यह है कि एक्स :: foo() विधि को कॉन्स्ट के रूप में घोषित किया जाता है - इसका मतलब है कि यह ऑब्जेक्ट को बदल नहीं सकता है (बदल सकता है)।

स्कोप्ड लॉक() कन्स्ट्रक्टर में एक अधिभार नहीं है जो एक म्यूटेक्स ऑब्जेक्ट के लिए एक अपरिवर्तनीय (कॉन्स्ट) संदर्भ स्वीकार करता है।

इसे ठीक करने के लिए आपको m_mutex को mutable के रूप में घोषित करने की आवश्यकता है, या उचित अधिभारित ScopedLock() कन्स्ट्रक्टर प्रदान करें। मैं सोच रहा हूं कि पूर्व बेहतर है।

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