2013-10-11 4 views
7

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

///////////Record.h///////////////////// 
#include "Base.h" 

class Derived1; 
class Derived2; 
template <class TYPE_LIST> class List; 

class FRecord 
{ 
public: 
    FRecord(); 
    virtual ~FRecord(); 

    friend class Base; 
#if _MSC_VER <= 1200 
    friend class List<Derived1>; 
    friend class List<Derived2>; 
#else 
    template <class TYPE_LIST> friend class List; 
#endif 
}; 

/////////////////////////////////////////////////////////////// 

///////////////////Base.h///////////////////////////////// 

class Base 
{ 
public: 
    Base(const HEADER *hc, const FRecord *fr); 
    virtual ~Base();  
    __inline bool IsNonValid() const; 

protected: 
    quint32 Size; 
}; 

///////////////////////////////////// 
// Data 
///////////////////////////////////// 
template <class TYPE_LIST> 
class Data : public TYPE_LIST 
{ 
public: 
    Data(const HEADER *hc, const FRecord *fr) : TYPE_LIST(hc, fr) 
    { 
     QString val = IsNonValid() ? "Non" : ""; 
     LOG0("Data ("<< val << " Valid)"); 
    } 

    virtual ~Data() 
    { 
     LOG0("Data deleted"); 
    } 
}; // Data 

/////////////////////////////////////////////////////////////////////////////////////// 

जब संकलित MSVC के साथ ऊपर कोड उत्पादन वांछित देता है, लेकिन यह त्रुटि निम्न देता है जब Mingw जीसीसी संकलक के साथ संकलित है,

Base.h:1154: error: there are no arguments to 'IsNonValid' that depend on a template parameter, so a declaration of 'IsNonValid' must be available 
Base.h:1553: error: 'Size' was not declared in this scope 

क्या इस समस्या का समाधान संभव हो सकता है ? अग्रिम धन्यवाद।

उत्तर

10

एमएसवीसी दो चरण नाम लुकअप को सही ढंग से लागू नहीं करता है। इस त्रुटि की रिपोर्ट करने में जीसीसी सही है।

कारण यह है कि टेम्पलेट के पैरामीटर पर निर्भर नहीं होने वाले नाम टेम्पलेट के पैरामीटर पर निर्भर नहीं हैं (वीसी के मामले में होना चाहिए) जब टेम्पलेट परिभाषित किया जाता है, तब यह तत्काल नहीं होता है।

आपके मामले में, कंपाइलर को यह कहने का कोई तरीका नहीं है कि IsNonValid बेस क्लास से आएगा, इसलिए यह सही तरीके से शिकायत करता है कि यह उसे नहीं जानता है। दो संभव समाधान कर रहे हैं:

  1. IsNonValid के लिए उपयोग योग्य, इतना है कि यह यह (संभावित) संकलक करने के लिए स्पष्ट है टेम्पलेट मापदंडों पर निर्भर करता है:

    QString val = this->IsNonValid() ? "Non" : ""; 
    
    // or 
    
    QString val = TYPE_LIST::IsNonValid() ? "Non" : ""; 
    
  2. में विरासत में मिला नाम का परिचय व्युत्पन्न वर्ग का दायरा:

    template <class TYPE_LIST> 
    class Data : public TYPE_LIST 
    { 
    public: 
        using TYPE_LIST::IsNonValid; 
        // the rest as you had it originally 
    

इनमें से किसी जब नाम TYPE_LIST का मान वास्तव में ज्ञात होता है, तब तक नाम निर्भर हो जाएगा और इस प्रकार इंस्टेंटेशन तक इसकी लुकअप स्थगित कर देगा।

+0

धन्यवाद @ एंग्यू: आपके समाधान ने मेरी समस्या हल की .:).. अब मैं अपने प्रश्न की स्थिति को हल करने के लिए कैसे बदल सकता हूं? – user2765235

+0

@ user2765235 उस उत्तर को स्वीकार करके जिसे आपने समस्या हल की है। आप उत्तर के बगल में हरे रंग के टिक-चिह्न पर क्लिक करके ऐसा करते हैं। अधिक जानकारी के लिए [सहायता] (http://stackoverflow.com/help/accepted-answer) देखें। – Angew

7

जीसीसी सही है। तत्काल समय तक लुकअप में देरी करने के लिए आपको this-> जोड़ने की आवश्यकता है।

this->IsNonValid();

MSVC गैर-अनुरूप में है कि यह इन्स्टेन्शियशन समय जब तक सभी लुकअप विलंब के रूप में यह ठीक से दो चरण नाम देखने को लागू नहीं करता है।

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