2013-10-11 32 views
7

我正在使用C++中的模板。使用MSVC編譯器編譯時以及使用Mingw gcc編譯器時,使用模板和好友類是否有區別。我的代碼在使用MSVC編譯時成功編譯並提供了所需的輸出,但在使用gcc編譯時會出錯。下面是我的代碼,對於不同的編譯器,C++模板類的行爲不同

///////////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 GCC編譯器編譯它提供了以下錯誤,

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

MSVC沒有正確實現兩階段名稱查找。 GCC在報告此錯誤時是正確的。

原因是模板內使用的名稱不依賴於模板的參數(應該是VC的情況下),而是在模板定義時查找,而不是在實例化時查找。

在你的情況,編譯器無法告訴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

謝謝@Angew:您的解決方案解決了我的問題。:)..現在怎樣才能將我的問題的狀態更改爲已解決? – user2765235

+0

@ user2765235接受你認爲解決問題的答案。您可以通過點擊答案旁邊的綠色勾號來做到這一點。有關更多信息,請參見[help](http://stackoverflow.com/help/accepted-answer)。 – Angew

7

gcc是正確的。您需要添加this->以延遲查找,直到實例化時間。

this->IsNonValid();

MSVC是不符合要求的,因爲它延遲所有查找,直到實例化時,因爲它不正確地實現兩階段名稱查找。

相關問題