2009-08-21 6 views
5

Ich habe einige Probleme mit diesem Code auf Linux kompilieren, aber es funktioniert perfekt in Windows.C++ Vorlage Problem in Cross-Plattform-Code

Windows-Compiler: Visual Studio 2005

Linux-Compiler gcc Version 3.4.3 20.041.212 (Red Hat 3.4.3-9.EL4)

class DoSomething 
{ 
    public: 
    template <class DataType> 
    bool Execute() 
    { 
     //do something here 
    } 
}; 


template <class Operator> 
TypeSwitch(int DataTypeCode, Operator& Op) 
{ 
    switch (DataTypeCode) 
    { 
    case 1: return Op.Execute<char>(); 
    case 2: return Op.Execute<int>(); 
    //snip; 
    } 
} 

//To call the operator 
TypeSwitch(Code,DoSomething); 

In Windows Dieser Code funktioniert perfekt und genau das tut, was ich will. In Linux, erhalte ich die Fehler:

Fehler: erwartete Primärausdruck vor ‚>‘ Token

Fehler: erwartete Primärausdruck vor ‚)‘ token

für jede der Leitungen mit dem Fall Erklärung.

Irgendwelche Ideen?

Danke, Mike

+0

Wich Linien werden die Fehler angezeigt? – Klaim

+0

Er sagt in seinem Beitrag: "für jede Zeile mit der Case-Anweisung." – DeusAduro

+0

Sind Sie sicher, dass der Code kompiliert? Ich kann mehrere Fehler sehen. Wo ist der TypeSwitch-Rückgabetyp? –

Antwort

13

Das Problem ist, dass, wenn der Compiler Op.Execute<char>(); trifft und versucht, es zu analysieren, es verwechselt wird.

Op ist ein abhängiger Name, daher weiß der Compiler nicht viel über seine Mitglieder. Es weiß also nicht, dass Execute eine Template-Funktion ist. Stattdessen wird davon ausgegangen, dass die < weniger als bedeutet. Das Sie versuchen, einige unbekannte Execute Mitglied zu etwas anderem zu vergleichen.

Anstatt also sollte die Zeile wie folgt aussehen:

case 1: return Op.template Execute<char>(); 

Jetzt ist der Compiler weiß, dass Execute eine Schablone, so dass, wenn es < trifft es nicht „weniger als“, sondern der Beginn der Schablone Parameter.

Das Problem ähnelt dem, wie Sie typename benötigen, wenn Sie Typen angeben, die zu einem abhängigen Namen gehören. Wenn Sie sich auf eine Template-Member-Funktion beziehen und die Template-Argumente explizit angegeben werden, benötigen Sie das Schlüsselwort template.

GCC-Verhalten ist korrekt, und MSVC ist zu nachsichtig. Wenn Sie das template Schlüsselwort hinzufügen, wird der Code in beiden Compiler arbeiten (und korrekt sein nach der Norm)

+2

Willkommen in der wundervollen, magischen Welt der C++ Template-Parser-Regeln! –

+0

Ah, danke! Ich werde es versuchen, wenn ich Montagmorgen wieder zur Arbeit komme, aber deine Beschreibung klingt genau richtig. Liebe einfach die Feinheiten mit Vorlagen! – miked

+0

Nur ein Follow-up für alle anderen, die das brauchen: Ich habe es gerade versucht und festgestellt, dass es einen bekannten Bug in MSVC gibt, dass der obige Fix nicht funktioniert. Also in Windows benötigen Sie Op.Execute () und in Not-Windows müssen Sie Op.template Execute (). – miked

1
case 1: return Op.template Execute<char>(); 
case 2: return Op.template Execute<int>(); 

See: template as qualifier

Auch TypeSwitch() gibt einen bool