2010-09-06 17 views
5

Con questo codice (solo una classe di test):Come avere una struttura con modello con una classe

typedef unsigned short UInt16; 

template<class T> 
class CClass 
{ 
public: 
    SValue* getNewSValue(void); 
private: 
    typedef struct { 
     T *mValue; 
     T *next; 
     T *previous; 
     UInt16 index; 
    } SValue; 
}; 

template<typename T> 
SValue* CClass<T>::getNewSValue(void) 
{ 
    return new SValue; 
} 

ho i seguenti errori:

error C2143: syntax error : missing ';' before '*'

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

è possibile utilizzare un Struct all'interno di una classe? Se dichiaro la struttura fuori dalla classe, il modello non vede il modello T.

+2

+1: questione ben formattata – Chubsdad

risposta

0

Sembra che lo struct non sia definito quando si dichiara il tipo di reso getNewSValue.

Con che non hanno tale errore:

template<class T> 
class CClass 
{ 
public: 
    SValue* getNewSValue(void); 
private: 
    typedef struct { 
     T *mValue; 
     T *next; 
     T *previous; 
     UInt16 index; 
    } SValue; 
}; 

template<typename T> 
SValue* CClass<T>::getNewSValue(void) 
{ 
    return new SValue; 
} 

E bisogna anche qualificare il tipo di SValue ritorno, perché è annidato in CClass quando lo si utilizza per definire getNewSValue.

0

Declare SValue prima getNewSValue():

template<class T> 
class CClass 
{ 
private: 
    typedef struct { 
     T *mValue; 
     T *next; 
     T *previous; 
     UInt16 index; 
    } SValue; 
public: 
    SValue* getNewSValue(void); 
}; 

Inoltre, assicurarsi UInt16 è definito.

3

$ 9,2/2- La chiave è la sotto citazione dal C++ Standard03

`Una classe è considerato un tipo completamente definito oggetto (3.9) (o di tipo completo) alla chiusura} della classe-specifier . All'interno della specifica dei membri della classe, la classe è considerata completa all'interno dei corpi delle funzioni, degli argomenti predefiniti e degli inizializzatori del costruttore (comprese le cose nelle classi annidate). Altrimenti è considerato incompleto all'interno della propria specifica membro della classe.

non sanno cosa è UINT16, ma il seguente dovrebbe funzionare

template<class T> 
class CClass 
{ 
private: 
    typedef struct { 
     T *mValue; 
     T *next; 
     T *previous; 
     short int index;      // Replacing with int for illustration only 
    } SValue; 
public: 
    SValue* getNewSValue(void); 
private: 
}; 

EDIT 3: La *** venuto lì cercando di fare il cambiamento BOLD (che avrei dovuto cancellato comunque)

template<class T> typename CClass<T>::SValue* CClass<T>::getNewSValue(void) 
{ 
    return new SValue; 
} 

int main(){ 
    CClass<int> s; 
    s.getNewSValue(); 
} 
+0

Qual è lo scopo del 'typename' keywork nella definizione di' getNewSValue'? Questo perché SValue è senza nome e dobbiamo fare riferimento ad esso usando il nome 'typedef'? –

+0

@Cedric se vogliamo omettere 'typename', sarebbe analizzato come la definizione di un membro chiamato' SValue' di classe 'CClass ', per cui non è stato specificato alcun tipo: 'tempate Classe :: SValue;'. I token seguenti sarebbero spazzatura e rifiutati dal compilatore come errori di sintassi. Questo perché il compilatore di default assume non-types se non può cercare un nome in fase di analisi (cioè non sa cosa sia 'T', quindi non può cercare' SValue'). Se inserisci 'typename',' SValue' è correttamente considerato come un typename per il membro 'getNewSValue'. –

+0

Il codice inserito genera il seguente errore: "errore C2244: 'CClass :: getNewSValue': impossibile associare la definizione della funzione a una dichiarazione esistente" – okami

0

come provarlo? ha funzionato su VS2008

template<class T> 
class CClass 
{ 
private: 
    typedef struct { 
     T *mValue; 
     T *next; 
     T *previous; 
     __int16 index; 
    } SValue; 

public: 
    SValue* getNewSValue(void) 
    { 
     return new SValue; 
    } 
}; 
0

Il Tipo SValue si trova all'interno del dominio CClass. Devi qualificare completamente il nome tipografico al di fuori della classe.

template<typename T> 
CClass<T>::SValue* CClass<T>::getNewSValue(void) 

Inoltre, è necessario rendere pubblico SValue, se restituito da un metodo pubblico.

0

Per la registrazione, nessuna di queste verrà compilata (almeno in GCC 4.2) non appena viene chiamata una chiamata allo getNewSValue(). Poiché si tratta di un metodo pubblico che restituisce un puntatore a un tipo privato, verrà visualizzato un errore di compilazione che indica che SValue is private.

Affinché questo funzioni, potrete sia necessario fare sValore pubblica, o modificare il tipo del valore di ritorno di getNewSValue() a qualcosa come void*, dal momento che sembra che stai cercando di fare sValue un tipo opaco.

1

Poiché la definizione della funzione membro è nell'ambito globale, è necessario qualificare il tipo di ritorno con CClass:: per fare riferimento al nome nell'ambito della classe. Inoltre, la parola chiave typename è necessaria quando si fa riferimento a nomi di tipo nidificati all'interno di modelli.

template<typename T> 
typename CClass<T>::SValue* CClass<T>::getNewSValue(void) 

Inoltre, la struttura nidificata è senza nome. Nota che in C++, le classi e le strutture hanno nomi propri e un nome typedef non è un nome di classe. Farai molto meglio a evitare il typedef.

struct SValue { 
    T *mValue; 
    T *next; 
    T *previous; 
    UInt16 index; 
}; 
+0

Questo è molto prolisso :-), Ma Potato il tuo codice genera il seguente err, sulla linea: typename CClass :: SValue * CClass :: getNewSValue (void) ERRORE ---> "errore C2899: typename non può essere utilizzato al di fuori di una dichiarazione modello" – okami

+0

@okami: mantenere la parte 'template '. Per una sintassi meno dettagliata, definire la funzione all'interno dell'ambito 'class {}'. Quindi 'typename' e qualification (su tipi locali della classe) non sono necessari. – Potatoswatter

Problemi correlati