2013-10-11 13 views
7

Sto lavorando con i modelli in C++. C'è qualche differenza nell'usare i template e la classe friend quando compilata con il compilatore MSVC e quando si usa il compilatore ging di Mingw. Il mio codice si compila con successo e fornisce l'output desiderato quando compilato con MSVC, ma dà errori quando è compilato con gcc. Qui di seguito è il mio codice,La classe template C++ si comporta in modo diverso per diversi compilatori

///////////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 

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

Quando compilato il codice precedente con MSVC dà uscita desiderata, ma quando si compila con Mingw compilatore GCC che dà seguente errore,

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 

quello che potrebbe essere la possibile soluzione a questo problema ? Grazie in anticipo.

risposta

10

MSVC non implementa correttamente la ricerca del nome in due fasi. GCC è corretto nel segnalare questo errore.

La causa è che i nomi utilizzati all'interno di un modello che non dipendono dai parametri del modello sono (dovrebbe essere nel caso di VC) cercati quando il modello è definito, non quando è istanziato.

Nel tuo caso, il compilatore non ha modo di dire che IsNonValid verrà dalla classe base, quindi giustamente si lamenta che non lo sa. Ci sono due possibili soluzioni:

  1. qualificare l'accesso a IsNonValid, in modo che sia chiaro al compilatore che (potenzialmente) dipende dai parametri del modello:

    QString val = this->IsNonValid() ? "Non" : ""; 
    
    // or 
    
    QString val = TYPE_LIST::IsNonValid() ? "Non" : ""; 
    
  2. inserire il nome ereditato nel portata della classe derivata:

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

Uno di questi renderà il nome dipendente e quindi rimandare la sua ricerca fino all'istnatia, quando il valore di TYPE_LIST è effettivamente noto.

+0

Grazie @Angew: la soluzione ha risolto il mio problema.:) ... Ora come posso modificare lo stato della mia domanda in SOLVED? – user2765235

+0

@ user2765235 Accettando la risposta che ritenete abbia risolto il problema. A tale scopo, fai clic sul segno di spunta verde accanto alla risposta. Consulta la [guida] (http://stackoverflow.com/help/accepted-answer) per maggiori informazioni. – Angew

7

gcc è corretto. È necessario aggiungere this-> per ritardare la ricerca fino al momento dell'istanziazione.

this->IsNonValid();

MSVC è non conforme dal fatto ritarda tutte le ricerche fino al momento istanziazione quanto non implementa correttamente ricerca di nome bifase.