मुझे नहीं लगता कि इनमें से कोई भी खराब बना हुआ है। सबसे पहले, using X::f2
, X
के लिए देखा गया है, और यह कक्षा प्रकार X
को अनजाने में उपज देगा। फिर f2
X
में देखा गया है, और यह भी अस्पष्ट है (यह D
में नहीं देखा गया है!)।
दूसरा मामला इसी कारण से काम करेगा।
लेकिन अगर आप कॉलf2
एक D
वस्तु पर, कॉल अस्पष्ट क्योंकि नाम f2
प्रकार X
की D
के सभी subobjects में देखा जाता है हो जाएगा, और D
इस तरह के दो subobjects है, और f2
एक गैर है -स्टैटिक सदस्य समारोह। दूसरे कारण के लिए एक ही कारण है। इससे Z::X
या X
का उपयोग करके f3
का नाम इस पर कोई फर्क नहीं पड़ता है। इनमें से दोनों कक्षा X
निर्दिष्ट करते हैं।
उपयोग घोषणा के लिए अस्पष्टता प्राप्त करने के लिए, आपको इसे अलग-अलग लिखना होगा। ध्यान दें कि सी ++ 0x using ThisClass::...;
में मान्य नहीं है। यह सी ++ 03 में है, हालांकि, जब तक पूरा नाम बेस-क्लास सदस्य को संदर्भित करता है।
इसके विपरीत, यह C++ 0x में अनुमति दी जाएगी अगर, घोषणा का उपयोग कर पूरी भी वैध, होगा क्योंकि C++ 0x नहीं नाम-देखने के लिए खाते में subobjects ले करता है: D::f2
स्पष्ट रूप से केवल एक ही घोषणा को संदर्भित करता है (X
में से एक)। DR #39 और अंतिम पेपर N1626 देखें।
struct D : Y, Z{
// ambiguous: f2 is declared in X, and X is a an ambiguous base class
using D::f2;
// still fine (if not referred to by calls/etc) :)
using Z::X::f3;
};
struct E : D {
// ambiguous in C++03
// fine in C++0x (if not referred to by an object-context (such as a call)).
using D::f2;
};
सी ++ 03 स्टैंडर्ड पैराग्राफ 10.2
और 3.4.3.1
में यह वर्णन करता है। Edit3 के लिए
प्रतिक्रिया:
हाँ, जीसीसी और VS2010 गलत हैं। trouble
::trouble
के इंजेक्शन क्लास नाम और Y::trouble
के रूप में पाए गए नेस्टेड क्लास द्वारा प्राप्त प्रकार को संदर्भित करता है। नाम trouble
::
पूर्ववर्ती (पहले बुलेट में 10.2
को 3.4.1/7
द्वारा, जो प्रतिनिधियों) अयोग्य देखने का उपयोग कर देखा जाता है किसी भी वस्तु, समारोह और प्रगणक नाम अनदेखी (3.4.3/1
- इस मामले में ऐसी कोई नाम हालांकि, वहाँ हैं)।
In a using-declaration used as a member-declaration, the nested-name-specifier shall name a base class of the class being defined.
यह:
If the resulting set of declarations are not all from sub-objects of the same type ... the program is ill-formed.
ऐसा नहीं है कि VS2010 और जीसीसी अलग तरह से व्याख्या C++ 0x शब्दों Comeau से है तथा वह पिछले कि शब्दों को लागू संभव है: यह तो 10.2
की आवश्यकता है कि के खिलाफ का उल्लंघन करती है इसका मतलब है कि गैर-बेस क्लास माना जाता है, लेकिन गैर-बेस क्लास नामित होने पर यह एक त्रुटि है। स्टैंडर्ड गैर आधार वर्ग के नाम की अनदेखी करने का इरादा चाहते हैं, तो इसे यहाँ कहेंगे केवल कर सकते हैं, या स्पष्ट रूप से यह उल्लेख (दोनों प्रथाओं किया जाता है)। मानक हालांकि के उपयोग के परिणामस्वरूप और कर सकते हैं। और जीसीसी सी ++ 0x शब्द लागू करता है, क्योंकि यह अन्यथा पूरी तरह से ठीक सी ++ 03 कोड को अस्वीकार करता है, सिर्फ इसलिए कि उपयोग की घोषणा में इसका वर्ग-नाम होता है।
अस्पष्ट शब्दों का एक उदाहरण के लिए, निम्न अभिव्यक्ति पर विचार करें:
a.~A();
क्योंकि यह एक सदस्य समारोह कॉल किया जा सकता है अगर a
एक वर्ग वस्तु है यह, वाक्य रचना अस्पष्ट है, लेकिन यह एक छद्म हो सकता है -डिस्टक्टर-कॉल (जो नो-ऑप है) यदि a
में स्केलर प्रकार है (जैसे int
)। लेकिन क्या स्टैंडर्ड कहते 5.2.4
पर एक छद्म नाशक कॉल और वर्ग के सदस्य के लिए उपयोग की वाक्य रचना के लिए है और 5.2.5
क्रमशः
The left-hand side of the dot operator shall be of scalar type.
For the first option (dot) the type of the first expression (the object expression) shall be “class object” (of a complete type).
गलत इस्तेमाल होता है यही कारण है, क्योंकि यह सब पर अस्पष्टता स्पष्ट नहीं है। इसे "केवल कर सकते हैं" का उपयोग करना चाहिए, और संकलक इस तरह से इसकी व्याख्या करते हैं। इसमें ज्यादातर ऐतिहासिक कारण हैं, क्योंकि कुछ समिति-सदस्य ने हाल ही में मुझे यूजनेट पर बताया था। The rules for the structure and drafting of International Standards देखें, अनुलग्नक एच।
डी में एक विधि जोड़ें जो f2() को कॉल करती है, देखें कि क्या होता है। –