2012-12-18 25 views
14
struct B {}; 
struct D : private B { 
    B* fun() { return new D; } // ok 
} 
struct DD : public D { 
    B* foo() { return 0; } // error: ‘struct B B::B’ is inaccessible ! 
}; 

यह त्रुटि मेरे लिए अनुचित लगती है। यदि हम वैश्विक दायरे में सरल B* का उपयोग कर सकते हैं तो क्यों इसकी निजी रूप से व्युत्पन्न कक्षाओं में नहीं? g++ demoबाद में निजी रूप से व्युत्पन्न कक्षाओं में बेस पॉइंटर/संदर्भ का एक साधारण उल्लेख क्यों प्रतिबंधित है?

हम B*, जो भाषा के नियमों (this, this, this से संबंधित हैं प्रश्न) द्वारा निषिद्ध है के लिए DD* कन्वर्ट करने के लिए कोशिश कर रहा है नहीं कर रहे हैं।
ध्यान दें कि, यदि मैं B* foo() से int foo() बदलता हूं, तो चीजें ठीक हो जाती हैं।

+1

एमएसवीसी 10.0 एक ही त्रुटि के साथ शिकायत करता है। – Yuushi

+0

@Yuushi, क्या एमएसवीसी [पब्बी के उत्तर] (http://stackoverflow.com/a/13927212/514235) के साथ त्रुटि को हल करता है?सिर्फ यह जानना चाहता था कि यह 'बग' को ठीक करने का मानक तरीका है या नहीं। – iammilind

+0

हां, यह ':: बी *' के साथ संकलित करता है। – Yuushi

उत्तर

7

तो स्पष्ट रूप से संकलक सोचता है कि B इस प्रकार के बजाय B के निजी निर्माता का जिक्र कर रहा है।

class B* foo() { return 0; } 

या इस:

योग्यता B जाहिरा तौर पर उस त्रुटि को ठीक करता

::B* foo() { return 0; } 

मैं क्यों कि क्या हो रहा है पता नहीं है, लेकिन शायद इस में मदद मिलेगी।


अद्यतन: शायद यह मानक के 11.2.4 से संबंधित है? एकमात्र समस्या यह है कि मेरा मानकीकरण पूरी तरह से समझने के लिए पर्याप्त नहीं है।

(छवि, प्रतिलिपि करने/चिपकाने के लिए खेद है मेरे लिए काम नहीं कर रहा है)

+0

यह मानते हुए कि 2 कंपाइलर 2 अलग-अलग प्लेटफार्मों पर एक ही त्रुटि की रिपोर्ट कर रहे हैं, मुझे लगता है कि यह मानक से संबंधित कुछ है या कुछ महत्वपूर्ण मसौदे, शायद "नाम संकल्प" के बारे में। – user1797612

+0

@ user1797612 हाँ, मैं सहमत हूं। – Pubby

1

मेरे सबसे अच्छा अनुमान है कि यह मना नहीं कर रहा है है, सी ++ बस उस बयान के अंदर बी प्रकार नहीं देखता या बेहतर शब्दों में लेबल B का अर्थ कुछ भी नहीं है।

कुछ अच्छा पढ़ने के बारे में

7

एक त्वरित स्टैंडर्ड पैदावार में इंजेक्शन-वर्ग-नाम के लिए लुक-अप:

§11.1 [class.access.spec]

5/ [ Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared. —end note ]

[ Example:

class A { }; 
class B : private A { }; 
class C : public B { 
    A *p; // error: injected-class-name A is inaccessible 
    ::A *q; // OK 
}; 

—end example ]

मेरा मानना ​​है कि इस डरते हुए अपने उदाहरण के करीब है;)


नोट बजना 3.0 के ढेर, जो थोड़ा अधिक स्पष्ट है:

$ clang++ -fsyntax-only test.cpp 
test.cpp:6:5: error: 'B' is a private member of 'B' 
    B* foo() { return 0; } // error: ‘struct B B::B’ is inaccessible ! 
    ^
test.cpp:2:12: note: constrained by private inheritance here 
struct D : private B { 
      ^~~~~~~~~ 
test.cpp:1:8: note: member is declared here 
struct B {}; 
    ^
1 error generated. 

यहाँ हम देखते हैं कि B के माध्यम से पहुँचा है वैश्विक नामस्थान में सीधे उठाए जाने के बजाय D

+0

+1: यह एक है :) –