टेम्पलेट क्लास में संरचना के साथ सी ++ संकलक मुद्दा


13

निम्नलिखित कोड gcc या क्लैंग के साथ संकलन नहीं करता है ।

template<class T>
class foo{};

template<class T>
class template_class_with_struct
{
    void my_method() {
        if(this->b.foo < 1);
    };

    struct bar
    {
        long foo;
    } b;
};

त्रुटि संदेश है

error: type/value mismatch at argument 1 in template parameter list for 'template<class T> class foo'    
    8 |         if(this->b.foo < 1);

त्रुटि templat वर्ग फू के कारण होती है। <1 के बजाय <= लिखते समय यह भी संकलित होता है।

किसी भी संकेत की सराहना की?

CompilerExplorer लिंक https://godbolt.org/z/v6Tygo


7
मैं कहूंगा कि संकलक कीड़े हैं, लेकिन msvc इसे स्वीकार करने वाला एकमात्र है: - / डेमो । संभावित काम आसपास b.bar::fooया कोष्ठक ( (this->b.foo) < 1)
Jarod42

जवाबों:


1

जीसीसी में, मुझे मिलता है

so.cpp:8:27: error: expected '>'
    if(this->b.foo < 1) 
                      ^

इसलिए, संकलक को लगता है कि fooउस लाइन पर fooऊपर वर्ग को संदर्भित करता है और एक टेम्पलेट तर्क की उम्मीद कर रहा है। यह वैसा ही है जैसा आप देख रहे हैं।

जब आप इसे बदल देते हैं <=, जो कि एक टोकन के रूप में लेसर द्वारा टोकन दिया जाता है। अगले चरण में ए भी नहीं दिखता है <, इसलिए यह इसे भ्रमित नहीं करता है।

यदि आप कक्षा को लंबे समय तक उसी नाम से नहीं बदलने के लिए बदलते हैं bar, तो यह समस्या नहीं है। इसके अलावा, @ Jarod42 ने आपके प्रश्न के लिए अपनी टिप्पणी में सुझाव दिए हैं (अधिक योग्यता या पारेंस)।

कंपाइलरों को चरणों में लिखा जाता है, जहां प्रत्येक चरण अगले के लिए बेहतर प्रतिनिधित्व के लिए कोड का अनुवाद करता है, और प्रत्येक चरण उस प्रतिनिधित्व के साथ अधिक से अधिक जटिल चीजें कर सकता है।

प्रारंभ में, संकलक "लेक्स" कोड, जो फ़ाइल में व्यक्तिगत पात्रों को टोकन की एक धारा में बदल देता है - यह इस रेखा को कुछ इस तरह से देखेगा

// if(this->b.foo < 1) 
- keyword(if)
- left-paren
- keyword(this)
- operator(->)
- name(b)
- operator(.)

और फिर यह हो जाता है foo। यह शायद करना चाहिए

- name(foo)
- operator(<)
- number(1)
- right-paren

लेकिन, यह मेरे जैसे दिखता है जब यह देखता है foo, यह आगे दिखता है, <और उस तथ्य को देखता है जो foo<class T>मौजूद है और यह एक एकल टोकन बनाने की कोशिश करता है foo< ...लेकिन फिर इसे >पूरा करने के लिए नहीं मिल सकता है।

यह सिर्फ एक अनुमान है - यह लेक्सर के अतीत का एक मंच हो सकता है जो नामों को खोजने की कोशिश करता है और टोकन को जोड़ सकता है। किसी भी मामले में, फू के कई उपयोग इसे धोखा दे रहे हैं।


मैं आपके स्पष्टीकरण को समझता हूं, लेकिन यह सुनिश्चित नहीं है कि इसका मतलब है कि संकलक को इस तरह से व्यवहार करना चाहिए। शायद यह अलग-अलग संकलक के लिए बग के रूप में फ़ील्ड होना चाहिए। कभी-कभी आप टेम्पलेट वर्गों (cnt, गिनती, काउंटर ... की तरह आम नाम) किसी लिंक किए गए पुस्तकालय हेडर के भीतर हैं क्या के बारे में पता नहीं हो सकता है
eactor

मुझे लगता है कि यह एक बग है, लेकिन मुझे नहीं पता कि कल्पना क्या कहती है। 3rd पार्टी हेडर के नाम होने से समस्या C ++ में एक सामान्य घटना है - आप आमतौर पर योग्यता के साथ हल कर सकते हैं।
लू फ्रैंको
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.