2012-07-23 12 views
5

Mam następujący kod:Korzystanie Częściowa specjalizacja w C++ 11

template<class T, int I=44> struct test {T j = I;}; 

template<int J> struct test<int, J> {int j = J;}; 

int main() 
{ 
    test<55> jj; 

    std::cout << jj.j << std::endl; 
    return(1); 
} 

Kompilator (szczęk) narzeka tylko o linii test<55> jj

Nie rozumiem dlaczego? Czy jest w pobliżu praca?

A jeśli narzeka na tę linię, dlaczego nie narzeka na drugą definicję szablonu?

Z góry dziękuję.

Przesłanie brzmi:

enable.cpp:17:8: error: template argument for template type parameter must be a type 
test<55> jj; 
    ^~ 
enable.cpp:9:16: note: template parameter is declared here 
template<class T, int I=44> struct test 
+0

Czy można połączyć komunikat o błędzie? – Morwenn

Odpowiedz

6

Problem polega na tym, że nie wiesz, jak działa wybór specjalizacji szablonu klasy.

Twoja specjalność:

template<int J> struct test<int, J> {int j = J;}; 

nie utworzyć szablon dla których trzeba tylko przejść w jednym int szablonu parametr.

test<55> jj; // doesn't work because there's no template<int J> struct test 

Zamiast co robi jest stworzenie specjalizacji template<class T, int I> struct test, który będzie używany podczas argumenty szablon do template<class T, int I> struct test dopasować specjalizacji, tj test<int,J>.

test<int,55> jj; // uses the specialization template<int J> struct test<int, J> 

Oto klucz cytat z normą:

w nazwie typu, które odnosi się do specjalizacji klasa szablonu (np A<int, int, 1>) wykaz argumentem powinien być zgodny z parametrem szablonu listę główny szablon. Argumenty szablonu o specjalizacji są wyprowadzane z argumentów szablonu podstawowego.[nacisk dodane]

                                                                                                                                                                - 14.5.5.1 [temp.class.spec.match] p4


Wydaje się, że próbuje ustawić int jako domyślny typ dla T przy jednoczesnym ustawianiu niezależnego domyślna wartość dla I. Myślę, że twoim zamiarem jest móc określić typ i wartość, określić tylko typ i uzyskać 44 jako wartość domyślną, lub podać tylko wartość i uzyskać int jako typ domyślny.

Niestety nie wiem, jak określić niezależne ustawienia domyślne. Możesz podać wartości domyślne (template<class T=int, int I=44> struct test), ale uzyskanie domyślnego typu będzie również wymagało zaakceptowania wartości domyślnej.

Jednakże, jeśli jesteś gotów użyć drugie imię to można zrobić:

template <int I> 
using test_int = test<int, I>; 

To tworzy alias szablonu tak, że trzeba tylko określić wartość:

test_int<55> jj; 

I skończy się to używaniem jakiejkolwiek specjalizacji, aby rozstrzygnąć, czy istnieje wyraźna specjalizacja, czy też kompilator generuje ukrytą.

3

Pierwszy błąd występuje, ponieważ kompilator próbuje wystąpienia parametru pierwszy szablonu (class T) z 55. To nie działa, ponieważ 55 nie jest sama w sobie rodzaj, ale powstanie tego. Jednakże, test<int> działa, ponieważ tutaj parater szablonu jest typem, zgodnie z żądaniem podpisu szablonu.

Zamiast tego chcesz "curry" dla typów, aka. szablon aliasing:

template <typename T> 
struct test2 = using test<T, 55>; 

Tutaj trzeba tylko zapewnić T do wyboru 55 postaci stałej drugiego parametru. Ale nadal musisz używać tego typu, nadając mu konkretną wartość: T, np. test2<double>.

Uwagi wskazany można być także zainteresowany następującymi Wariant:

template <int I> 
using test3 = test<int, I>; 

Tutaj naprawić pierwszy parametr typu int, która pozwala na wykorzystanie go jak to było w kodzie:

test3<55> t; 
+0

W kodzie jest tak wiele błędów ... Po pierwsze, składnia oczywiście zawodzi. Po drugie, nie chce określać typu. Po trzecie, nie jest to częściowa specjalizacja. – Xeo

+3

Specjalizacja naprawia T na int i używa 55 tylko jako wartości, której używa. Prawdopodobnie szukasz "szablonu przy użyciu test_int = test ;' zamiast tego. – bames53

+0

Aliasing szablonu w odpowiedzi jest równoważny wartości domyślnej, co nie jest tym, czego naprawdę chce użytkownik. –

Powiązane problemy