2010-06-25 12 views
6

Przekazuję mój kod C++ (msvc & intel) do Linuksa (g ++). Kod używa wielu szablonów (lubię metaprogramowanie ;-). Ale nie mogę skompilować ten kod:g ++ Problem szablonu

template <class TA> 
struct A 
{ 
    template <class TAB> struct B; 
}; 


template <class TC> 
struct C {}; 


template <class TD> 
struct D 
{ 
    template <class TTD> class T {}; 
}; 


template<class TA> 
    template<class TBA> 
struct A<TA>::B : C<typename D<TA>::T<TBA> > 
{ 
    int foo; 
}; 

g ++ mówi mi, że w definicji A :: B, C klasa ma nieprawidłowe argumenty szablonu. Ale na msvc i intel działa dobrze! Jaki jest problem? PS: Niestety, nie mogę opublikować oryginalnego kodu, ponieważ jest zbyt skomplikowany w stosunku do szablonu. Ale ten przykład jest praktycznie taki sam i daje taki sam błąd w g ++. Dziękuję.

AKTUALIZACJA: Znalazłem problem z argumentem TBA z T. g ++, który nie przypomina użycia drugiego szablonu w definicji.

+0

widziałem, że „szablon szablon struct ...” składni wcześniej, ale nigdy nie wiadomo, co to znaczy lub dlaczego jest to prawna składnia. Co to znaczy (kiedy "szablon" jest wymieniany dwa razy przed taką strukturą)? – Dennis

+1

@Dennis: Jest potrzebny do definicji zagnieżdżonych szablonów poza szablonem, na przykład [tutaj] (http://www.comeaucomputing.com/techtalk/templates/#outsidedef). –

+0

TA jest argumentem szablonu A, a TAB jest argumentem szablonu A :: B – f0b0s

Odpowiedz

10

Musisz template słowa kluczowego

template<class TA> 
    template<class TBA> 
struct A<TA>::B : C<typename D<TA>::template T<TBA> > 
{ 
    int foo; 
}; 

GCC jest poprawny dać diagnostyczny tutaj. Wynika to z faktu, że T nie można wyszukać w zakresie zależnym D<TA>. Znaczenie < po tym zależy od tego, czy T jest szablonem, czy nie. Standard mówi, że przyjmuje się, że T nie jest szablonem, a zatem T nie może być śledzony przez listę szablonów argumentów.

template jest jak typename w to, że informuje kompilator traktować T jako szablon i że < jest początek listy argumentów w każdym przypadku. Standard mówi w ust 14.2/2 i 14.2/4

Dla nazwa-szablonu zostać wyraźnie określony poprzez argumenty szablonu, nazwa musi być znana odnieść do szablonu.

Po wyświetleniu nazwy specjalizacji szablonu członka. lub -> w wyrażeniu Postfiks lub po specyfikatorze nazwy zagnieżdżonej w kwalifikowanym-id, a wyrażenie przyrostkowe lub kwalifikowany identyfikator jawnie zależy od parametru-szablonu (14.6.2), nazwa szablonu elementu musi być prefiksowany przez szablon słów kluczowych. W przeciwnym razie przyjmuje się, że nazwa nie jest szablonem.

W twoim przypadku, masz T pojawi się po zagnieżdżonego-NAME specyfikatorem D<TA> która zależy od szablonu-parametru TA. Aby specyfikator typename mógł poprawnie parsować, konstrukt D<TA>::T<TBA> musi interpretować T jako nazwę szablonu klasy, który zabrania stosowania 14.2.


na ten temat, to zawsze dobry pomysł, aby spróbować skompilować z Clang

main1.cpp:21:37: error: use 'template' keyword to treat 'T' as a dependent template name 
struct A<TA>::B : C<typename D<TA>::T<TBA> > 
            ^
            template 
1 error generated. 
+1

BRILLIANT, THANX! – f0b0s

+0

ok, rozumiem.Mam na myśli drugie słowo kluczowe "typename", ale teraz "szablon". – f0b0s

+0

Wow, bardzo podoba mi się ten komunikat diagnostyczny, teraz tego właśnie oczekujesz od idealnego kompilatora. –

Powiązane problemy