2013-01-14 20 views
10

Vedo un errore relativo ai modelli (il compilatore è Visual Studio 2012) che non capisco. Ecco il codice, bollito fino all'essenziale:Definizione della funzione membro di classe esplicitamente specializzata al di fuori della definizione della classe

// Templated class - generic 
template <typename T> 
class Test 
{ 
    public: 
     void WorksFine() {} // Comiples and works as expected at runtime 
     void Problem();  
}; 

// Templated class - expicit specialization for T = int. 
template <> 
class Test<int> 
{ 
     public: 
      void WorksFine() {} // Comiples and works as expected at runtime 
      void Problem(); 
}; 

// The definition below compiles and works fine at runtime. 
template<typename T> void Test<T>::Problem() {} 


// The definition below gives error C2910. 
template<> void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");} 

Per il metodo WorksFine, la definizione della funzione è all'interno della definizione di classe esplicitamente specializzata, ed è tutto a posto. Ma per il metodo Problem, quando definisco il metodo al di fuori della definizione di classe esplicitamente specializzata, ottengo l'errore C2910

Perché è questo? Errore C2910 indica che il problema è che Test :: Problem() è già definito. Ma è non definito all'interno della classe ... non esiste una definizione di funzione solo una dichiarazione.

Sembra abbastanza difficile essere in grado di fare qualcosa o meno a seconda di dove si sceglie di mettere la definizione della funzione, che ho sempre avuto più di una decisione stile/sintassi, non una decisione di funzionalità/semantica. Mi sto perdendo qualcosa?

risposta

8

Non è necessario il template<>. Basta scrivere:

void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");} 

La template<> sintassi su una specializzazione membro è tenuto in cui istanziare esplicitamente un membro sulla propria; viene omesso quando si definisce un membro di una specializzazione già esistente.

template<typename T> struct X { static int i; }; 
template<> int X<int>::i = 0; // member instantiation, uses template<> 

template<typename T> struct Y { static int i; }; 
template<> struct Y<int> { static int i; } // template specialization 
int Y<int>::i = 0; // no template<> 
+0

Grazie , che funziona davvero! –

0

Non hai bisogno di più template nella definizione della funzione esplicita: void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}

In questo caso g ++ dà un messaggio di errore leggermente migliore error: template-id 'Problem<>' for 'void Test<int>::Problem()' does not match any template declaration

0

Prova questo:

// The definition below gives error C2910. 
void Test<int>::Problem() 
{ 
    printf("In Test::Problem(int instantiation)\n"); 
} 

int main() 
{ 
    Test<int> hey; 

    hey.Problem(); 
    return 0; 
}; 
+0

Grazie, è tutto! –

+0

@DavidStone :) Nessun problema! – tmaric

Problemi correlati