26

कृपया नीचे दिए गए कोडका उपयोग कर-घोषणा का एक अजीब व्यवहार

struct A { using type = int; }; 
struct B : private A {}; 
struct C : B { using base_type = A; }; 

जीसीसी 6.1 के सभी बजना 3.8 देखते हैं, और MSVC 2015 अपडेट 3, इस संकलन से इंकार कर दिया के रूप में A के बाद से C अंदर एक सुलभ नाम नहीं है AB का एक निजी आधार है। ऐसा लगता है कि जीसीसी Ausing base_type = A में A के डिफ़ॉल्ट कन्स्ट्रक्टर को संदर्भित करता है। एमएसवीसी और क्लैंग नहीं लग रहा है।

शायद संकलन त्रुटि विरासत से शुरू हो रहा नामों में से इंजेक्शन की वजह से है (क्योंकि संशोधित using base_type = ::A में using base_type = A सब compilers ठीक से काम कर रहे हैं), लेकिन मैं अगर यह अजीब त्रुटि क्या मानक का कहना है जानना चाहते हैं।

अधिक वस्तुतः,

  1. के रूप में मैं समझ गया, A::type पसंद नहीं, A सिर्फ एक वर्ग के नाम है (हालांकि एक समारोह नाम के रूप में जीसीसी misinterprets यह) जो Cनहीं अंदरA है और न ही B के लिए शुरू की है। इस नाम को B पर निजी क्यों माना जाता है?
  2. क्या इस संकलन त्रुटि को बग माना जाना चाहिए, या मानक के विनिर्देशों का एक बढ़त मामला होना चाहिए?
+1

मुझे लगता है कि यह 'सी' कार्यों के अंदर 'ए' के ​​लिए नाम लुकअप के कारण है।सबसे पहले यह जांचने के लिए जांच करता है कि 'उपयोग' से पहले 'सी' के दायरे में 'ए' नाम से कुछ भी घोषित किया गया है या नहीं। चूंकि इसे कोई नहीं मिलता है, इसलिए यह बेस बी के बाद से 'बी' के दायरे में इसकी जांच कर रहा है। और यदि उसे 'बी 'के दायरे में' ए' नहीं मिलता है, तो यह 'वैश्विक नामस्थान' में दिखाई देगा। लेकिन किसी भी तरह 'बी 'द्वारा' ए' की 'निजी विरासत' को दूसरी बी लुक में रोक दिया जा रहा है, जिसे' बी' के दायरे में रखा गया है। चूंकि यह 'पूरी तरह योग्य' नाम का उपयोग करके काम करता है, जिससे मुझे लगता है कि वास्तविक समस्या एक ही पंक्ति पर होनी चाहिए। – Arunmu

+4

http://eel.is/c++draft/class.access.spec#5 प्रासंगिक लगता है –

+0

@PiotrSkotnicki धन्यवाद, यह सीधे सवाल का जवाब देता है। लेकिन, क्या आप मुझे इस नियम के पीछे तर्कसंगत दे सकते हैं? –

उत्तर

28

unqualified name lookup के नियम के अनुसार:

(जोर मेरा)

एक अयोग्य नाम के लिए, कि एक ऐसा नाम है जो एक गुंजाइश संकल्प ऑपरेटर के अधिकार के लिए प्रकट नहीं होता है :: , नाम लुकअप नीचे वर्णित स्कॉप्स की जांच करता है, जब तक कि इसे किसी भी प्रकार की कम से कम एक घोषणा नहीं मिलती, उस समय लुकअप बंद हो जाती है और आगे कोई स्कॉप्स की जांच नहीं की जाती है

तो नाम A बेस क्लास स्कोप पर सबसे पहले मिलेगा, वैश्विक नामस्थान में नाम यहां नहीं माना जाएगा। उसके बाद, सही जांच का उपयोग किया जाता है और फिर संकलित विफल हो जाता है।

और ::A वैश्विक दायरे में नाम निर्दिष्ट करता है और इस मुद्दे को हल करता है, जो इसे qualified name lookup बनाता है।

2

पोस्ट करना जवाब के रूप में मेरी टिप्पणी (एक जवाब एक टिप्पणी से भी अधिक की तरह लगता है):

मैं इस अनुमान लगा रहा हूँ AC अंदर कार्यों के लिए कैसे नाम देखने के कारण है। सबसे पहले यह जांचने से पहले C के दायरे में A नाम से कुछ भी घोषित किया गया है या नहीं। चूंकि इसे कोई नहीं मिलता है, इसलिए यह बेस क्लास के बाद B के दायरे में इसकी जांच कर रहा है। और में यह बीएस स्कोप में ए नहीं मिला है, यह global namespace में दिखाई देगा। लेकिन B द्वारा A की निजी विरासत B के दायरे के अंदर दूसरे लुकअप में बंद हो रही है। चूंकि यह fully qualified नाम का उपयोग कर काम करता है, जिससे मुझे लगता है कि वास्तविक समस्या एक ही पंक्ति पर होनी चाहिए।

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