2011-10-25 9 views
15

Questo piccolo pezzo di codice innesca la rabbia del linker quando incluso in almeno due unità di traduzione (file CPP):Perché il linker si lamenta di più definizioni in questo modello?

# ifndef MAXIMUM_HPP 
# define MAXIMUM_HPP 

template<typename T> 
T maximum(const T & a, const T & b) 
{ 
    return a > b ? a : b ; 
} 

/* dumb specialization */ 
template<> 
int maximum(const int & a, const int & b) 
{ 
    return a > b ? a : b ; 
} 

# endif // MAXIMUM_HPP 

Ma compila e collega bene con una sola unità di traduzione. Se rimuovo la specializzazione, funziona bene in tutte le situazioni. Ecco il messaggio del linker:

g++ -o test.exe Sources\test.o Sources\other_test.o 
Sources\other_test.o:other_test.cpp:(.text+0x0): multiple definition of `int maximum<int>(int const&, int const&)' 
Sources\test.o:test.cpp:(.text+0x14): first defined here 

Non è possibile creare più istanze di modelli? Come spiegare questo errore e come risolverlo?

Grazie per qualsiasi consiglio!

+0

Probabilmente dovrebbe restituire un riferimento da vostre funzioni. – Dani

+0

Era solo un esempio derivante dal rintracciare gli errori che ho riscontrato in un codice più complesso. Penso che l'esempio possa essere più chiaro senza alcun riferimento :) – overcoder

risposta

30

È perché le specializzazioni complete del modello esplicito devono essere definite una sola volta - Sebbene il linker consenta di definire più volte le specializzazioni implicite, non consente specializzazioni esplicite, le considera semplicemente come una funzione normale.
Per correggere questo errore, mettere tutte le specializzazioni nel file sorgente come:

// header 

// must be in header file because the compiler needs to specialize it in 
// different translation units 
template<typename T> 
T maximum(const T & a, const T & b) 
{ 
    return a > b ? a : b ; 
} 

// must be in header file to make sure the compiler doesn't make an implicit 
// specialization 
template<> int maximum(const int & a, const int & b); 

// source 

// must be in source file so the linker won't see it twice 
template<> 
int maximum(const int & a, const int & b) 
{ 
    return a > b ? a : b ; 
} 
+0

Sono più che grato! Stavo per chiederti come riscrivere il file di intestazione! – overcoder

11

Dichiarare le funzioni in linea

// must be in header file because the compiler needs to specialize it in 
// different translation units 
template<typename T> 
inline T maximum(const T & a, const T & b) 
{ 
    return a > b ? a : b ; 
} 

/* dumb specialization */ 
template<> 
inline int maximum(const int & a, const int & b) 
{ 
    return a > b ? a : b ; 
} 
+1

Mille grazie! Penso che possiamo ottenere una risposta completa e precisa se potessimo fondere la tua con la risposta di Dani. – overcoder

Problemi correlati