2010-06-25 17 views
6

Ich portiere meinen C++ Windows-Code (msvc & Intel) nach Linux (g ++). Der Code verwendet viele Vorlagen (Ich mag Metaprogrammierung ;-). Aber ich kann diesen Code nicht kompilieren:g ++ Vorlage Problem

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 ++ mir sagt, dass in der Definition von A :: B, C-Klasse ungültig Vorlage Argumente hat. Aber auf MSVC und Intel funktioniert es gut! Was ist das Problem hier? PS: Entschuldigung, ich kann den Originalcode nicht posten, weil er zu aufwendig ist. Aber dieses Beispiel ist praktisch das gleiche und gibt den gleichen Fehler auf g ++. Danke.

UPDATE: Ich habe das Problem gefunden ist in TBA Argument von T. g ++ Doesn nicht wie die Verwendung von zweiten Vorlage in der Definition.

+0

Ich habe, dass „Vorlage Vorlage Struktur ...“ Syntax gesehen zu kompilieren, aber ich habe noch nie bekannt, was es bedeutet oder warum es legale Syntax ist. Was bedeutet es (wenn "Template" zweimal vor einer solchen Struktur erwähnt wird)? – Dennis

+1

@Dennis: Es wird für die Definition von verschachtelten Vorlagen außerhalb der umschließenden Vorlage benötigt, siehe z.B. [hier] (http://www.comeaucomputing.com/techtalk/templates/#outsidedef). –

+0

TA ist ein Template-Argument von A, und TAB ist ein Template-Argument von A :: B – f0b0s

Antwort

10

Sie benötigen die template Stichwort

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

GCC korrekt ist eine diagnostische hier zu geben. Dies liegt daran, dass T nicht im abhängigen Bereich D<TA> nachgeschlagen werden kann. Die Bedeutung der < hängt davon ab, ob T eine Vorlage ist oder nicht. Der Standard besagt, dass T als keine Vorlage angenommen werden soll und daher auf T keine Template-Argumentliste folgen kann.

template ist wie typename, dass es den Compiler sagt T als Vorlage zu behandeln und dass die < ist der Beginn einer Argumentliste auf jeden Fall. Die Norm sagt in den Absätzen 14.2/2 und 14.2/4

für eine Vorlage-Namen explizit durch die Vorlage Argumente zu qualifizieren, muss der Name in eine Vorlage verweisen bekannt.

Wenn der Name einer Mitgliedervorlagenspezialisierung nach erscheint. oder -> in einem Postfix-Ausdruck oder nach einem Nested-Name-Spezifizierer in einer qualifizierten ID, und der Postfix-Ausdruck oder die qualifizierte ID hängt explizit von einem Template-Parameter (14.6.2) ab, muss der Member Template-Name sein Präfix der Keyword-Vorlage. Andernfalls wird angenommen, dass der Name ein Nicht-Template bezeichnet.

In Ihrem Fall haben Sie T nach dem verschachtelten-name-specifier D<TA> erscheinen die TA auf dem Template-Parameter abhängig ist. Damit der typname-specifier korrekt analysiert wird, muss das Konstrukt D<TA>::T<TBA>T als den Namen einer Klassenvorlage interpretieren, die 14.2 verbietet.


zu diesem Thema, es ist immer eine gute Idee zu versuchen und mit 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, ich habe es.Ich rufe etwa das zweite 'typename' Keyword, aber jetzt eine 'Vorlage'. – f0b0s

+0

Wow, ich mag diese Diagnosemeldung wirklich, jetzt erwartet man das vom idealen Compiler. –