c++ - जीसीसी मुद्दा: बेस क्लास के सदस्य का उपयोग करना जो टेम्पलेट तर्क पर निर्भर करता है




templates base-class (4)

निम्नलिखित कोड जीसीसी के साथ संकलित नहीं है, लेकिन विजुअल स्टूडियो के साथ करता है:

template <typename T> class A {
public:
    T foo;
};

template <typename T> class B: public A <T> {
public:
    void bar() { cout << foo << endl; }
};

मुझे त्रुटि मिलती है:

test.cpp: सदस्य फ़ंक्शन 'शून्य बी :: बार ()' में:

test.cpp: 11: त्रुटि: इस गुंजाइश में 'foo' घोषित नहीं किया गया था

लेकिन यह होना चाहिए! अगर मैं bar बदलता हूं

void bar() { cout << this->foo << endl; }

तो यह संकलित करता है , लेकिन मुझे नहीं लगता कि मुझे यह करना है। क्या सी ++ के आधिकारिक चश्मा में कुछ है कि जीसीसी यहां चल रहा है, या यह सिर्फ एक क्विर्क है?


डेविड जॉयनेर का इतिहास था, यही कारण है।

B<T> संकलित करते समय समस्या यह है कि इसकी बेस क्लास A<T> कंपाइलर से अज्ञात है, टेम्पलेट क्लास होने के कारण, कंपाइलर को बेस क्लास से किसी भी सदस्य को जानने का कोई तरीका नहीं है।

पहले के संस्करणों ने वास्तव में आधार टेम्पलेट वर्ग को पार्स करके कुछ अनुमान लगाया था, लेकिन आईएसओ सी ++ ने कहा कि यह अनुमान उन संघर्षों का कारण बन सकता है जहां नहीं होना चाहिए।

टेम्पलेट में बेस क्लास सदस्य का संदर्भ देने का समाधान इसका उपयोग this (जैसे आपने किया) या विशेष रूप से बेस क्लास का नाम दें:

template <typename T> class A {
public:
    T foo;
};

template <typename T> class B: public A <T> {
public:
    void bar() { cout << A<T>::foo << endl; }
};

जीसीसी मैनुअल में अधिक जानकारी।


यह gcc-3.4 में बदल गया। सी ++ पार्सर को उस रिलीज में बहुत अधिक सख्त मिला - spec के प्रति लेकिन विरासत या बहु-मंच कोड अड्डों वाले लोगों के लिए अभी भी परेशान है।


वीसी दो चरण के लुकअप को लागू नहीं करता है, जबकि जीसीसी करता है। इसलिए जीसीसी तत्काल होने से पहले टेम्पलेट को पार करती है और इस प्रकार वीसी की तुलना में अधिक त्रुटियां पाती हैं। आपके उदाहरण में, foo एक आश्रित नाम है, क्योंकि यह 'टी' पर निर्भर करता है। जब तक आप संकलक को यह नहीं बताते कि यह कहां से आता है, यह टेम्पलेट की वैधता की जांच नहीं कर सकता है, इससे पहले कि आप इसे तुरंत चालू करें। यही कारण है कि आपको कंपाइलर को यह बताना होगा कि यह कहां से आता है।


सी ++ का मुख्य कारण यहां कुछ भी नहीं मान सकता है कि आधार टेम्पलेट को बाद में एक प्रकार के लिए विशेषीकृत किया जा सकता है। मूल उदाहरण जारी रखना:

template<>
class A<int> {};

B<int> x; 
x.bar();//this will fail because there is no member foo in A<int>




name-lookup