2010-07-22 15 views
6

Ho un problema riguardante l'inizializzazione del membro 'const const'. In una classe basata su modelli definisco un membro const e lo inizializzo al di fuori della classe.
Quando includo il file .h in cui questa classe è implementata in più file .cpp, viene visualizzato un errore LNK2005 (sto usando VS2010) che dice che la costante è già definita.Inizializzazione di membri cost const nella classe di modelli

// List.hpp 
template <class T> 
class List { 
    static const double TRIM_THRESHOLD; 
}; 

template <class T> 
const double List<T>::TRIM_THRESHOLD = 0.8; 

Ho provato a mettere l'inizializzazione membro in un file cpp, ma tanto sono un errore di linker dicendo che la costante non è definita a tutti. Se la lista non è basata su modelli e inserisco l'inizializzazione in un file .cpp, va tutto bene.
C'è qualche soluzione per questa situazione? Ho già le clausole # ifdef/define attorno al file, e non è sicuramente una soluzione.

+1

Manca il modificatore "const" nella definizione. – Ropez

+1

Sei sicuro che questo sia il tuo codice? Non dovresti avere errori. @Ropez: il 'const' conta solo nella dichiarazione. – GManNickG

+0

È interessante notare che VS2015 non ha questo problema. In qualche modo è possibile ottimizzare/capire che le definizioni di const statiche sono in realtà tutte la stessa cosa e non contrassegnano un errore nel linker. – Menace

risposta

7

È necessario definire la costante in un file di origine non un'intestazione (in modo che venga definita solo una volta) poiché questo è un modello che è necessario conservare nell'intestazione (e tutte le istanze hanno lo stesso valore) è possibile utilizzare un classe base comune.

class ListBase { 
protected: 
    ListBase() {} // use only as base 
    ~ListBase() { } // prevent deletion from outside 
    static const double TRIM_THRESHOLD;  
}; 

template <class T> 
class List : ListBase { 
}; 

// in source file 
double ListBase::TRIM_THRESHOLD = 0.8; 

Un'altra opzione è quella di avere come una funzione statica:

static double trim_threashold() { return 0.8; } 

Edit: Se il compilatore C++ supporta 11 fate il vostro metodo di static un constexpr function in modo che ha tutte le opportunità di ottimizzazione che utilizza direttamente il valore.

+0

Penso che il tuo punto sia sbagliato. Guarda http://stackoverflow.com/questions/1553854/template-static-variable – cybevnm

+1

non penso che abbia torto, perché viene usato l'ereditarietà, dove il membro statico si trova nell'antenato che non è il modello. quindi usare la funzione statica è anche valido. – uray

+0

Se abbiamo bisogno dello stesso valore costante per ciascuna delle istanze del modello (TRIM_THRESHOLD è uguale per l'Elenco o Elenco ), la soluzione di Motti è giusta. Se è necessario farlo solo per evitare errori di linker (più definizioni dello stesso simbolo), questa soluzione è eccessiva. La lingua ci consente di definire la variabile statica della classe template nell'intestazione. Se Motti intendeva il primo caso - mi chiedo, perché non ho capito il suo punto. – cybevnm

Problemi correlati