2013-01-14 13 views
10

Widzę błąd związany z szablonami (kompilator to Visual Studio 2012), których nie rozumiem. Oto kod, sprowadzała się do tego, co istotne:Definiowanie funkcji składowej jawnie wyspecjalizowanej klasy poza definicją klasy

// 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");} 

Dla metody WorksFine, definicja funkcji jest wewnątrz jawnie wyspecjalizowanym definicja klasy, i wszystko jest w porządku. Ale w przypadku metody Problem, kiedy definiuję metodę poza definicją wyraźnie wyspecjalizowanej klasy, pojawia się błąd C2910

Dlaczego tak jest? Błąd C2910 wskazuje, że problem polega na tym, że Test :: Problem() jest już zdefiniowany. Ale jest to nie zdefiniowane w klasie ... nie ma definicji funkcji tylko deklaracja.

Wydaje się być kulawym móc coś zrobić lub nie, w zależności od tego, gdzie zdecydujesz się umieścić definicję funkcji, co zawsze było bardziej decyzją o stylu/składni, a nie decyzją o funkcjonalności/semantyki. Czy czegoś brakuje?

Odpowiedz

8

Nie potrzebujesz template<>. Wystarczy napisać:

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

Składnia template<> na specjalizacji członek jest wymagane, jeżeli wyraźnie instancji członek na własną rękę; jest pomijany przy definiowaniu członka już istniejącej specjalizacji.

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

Thanks , to rzeczywiście działa! –

0

Nie trzeba template już w wyraźnej definicji funkcji: void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}

W tym przypadku g ++ daje nieco lepszy komunikat o błędzie error: template-id 'Problem<>' for 'void Test<int>::Problem()' does not match any template declaration

0

Spróbuj tego:

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

Dzięki, to wszystko! –

+0

@DavidStone :) Nie ma problemu! – tmaric

Powiązane problemy