2012-01-03 19 views
7

następujący kod:C++: częściowa specjalizacja szablonu klas szablonu

using namespace std; 

template <typename X> 
class Goo {}; 


template <typename X> 
class Hoo {}; 


template <class A, template <typename> class B = Goo > 
struct Foo { 
    B<A> data; 
    void foo1(); 
    void foo2(); 

}; 


template <typename A> 
void Foo<A>::foo1() { cout << "foo1 for Goo" << endl;} 


int main() { 
    Foo<int> a; 
    a.foo1(); 

} 

daje mi błąd kompilatora:

test.cc:18: error: invalid use of incomplete type 'struct Foo<A, Goo>' 
test.cc:11: error: declaration of 'struct Foo<A, Goo>' 

Dlaczego nie mogę częściowo specjalizują foo1()? Jeśli to nie jest sposób, w jaki sposób mogę to zrobić?

Mam inne pytanie: co jeśli chcę, aby foo2() było zdefiniowane tylko dla A = int, B = Hoo i nie dla żadnej innej kombinacji, jak to zrobić?

+1

To nie jest częściowa specjalizacja, Foo przyjmuje dwa parametry i podacie tylko jedną w 'Foo :: foo1'. –

+0

Co to jest X w Goo . Goo jest szablonem przyjmującym parametr X. Gdzie jest określony? – jmucchiello

Odpowiedz

4

Szablony funkcji mogą być wyłącznie w pełni wyspecjalizowane, nie częściowo.

funkcje użytkownika szablonów klasy są automatycznie funkcjonować szablonów i mogą rzeczywiście być wyspecjalizowane, ale tylko w pełni:

template <> 
void Foo<int, Goo>::foo1() { } // OK 

Można częściowo specjalizują całą klasę a następnie zdefiniować go na nowo:

template <typename A> 
struct Foo<A, Goo> 
{ 
    // ... 
}; 

(patrz 14.7.3 szczegóły.)

+0

Nie sądzę, że próbuje nawet specjalizować. Edycja: Ach właśnie, przez "częściową specjalizację" chce on pominąć jeden z parametrów. – someguy

+0

Więc nie ma sposobu, aby częściowo wyspecjalizować metodę elementu klasy szablonu, bez specjalizacji całej klasy? – user231536

+0

@ user231536: Nie, rzeczywiście. Oto [podobna, poprzednia odpowiedź] (http://stackoverflow.com/a/7517290/596781). –

1

szablon nadal ma dwa parametry, a ty m ust wpisz coś takiego:

template <typename A, template <typename> class B> 
void Foo<A,B>::foo1() { cout << "foo1" << endl;} 

Ustawiono wartość domyślną i należy ją podać tylko raz. Odtąd jest to jak każdy inny szablon z dwoma parametrami. Ten kod będzie obowiązywał bez względu na to, co B jest (domyślnie lub inaczej). Jeśli chcesz określić inne zachowanie dla określonego B, , a następnie, możesz specjalizować się w klasie, a nie tylko w metodzie.

(Mocno edytowany)

+0

Myślę, że niektóre kombinacje odpowiedzi @ KerreckSB, a może moje, mogą być poprawne. Nie jestem pewien, jaki jest ostateczny cel. Ostatecznie, myślę, że całkowicie nieskategoryzowane 'foo1()' będzie musiało być wdrożone prędzej czy później, tak jak to, które napisałem. –

Powiązane problemy