2010-10-17 8 views
18

Ich erhalte einen Fehler <: kann eine Template-Argumentliste auf g ++ Compiler nicht beginnen.<: kann eine Template-Argumentliste nicht beginnen

Code
template<typename T> class SomeClass; 
class Class; 

SomeClass<::Class>* cls; 
+1

Die neue standrard (C++ 0x) befasst sich mit der Frage der >> wie in A >. Geht es nicht auch um dieses Problem? Übrigens, Micorosoft Compiler geben keine Fehler auf diese (ich weiß, dass sie technisch sollten, aber es ist gut, sie nicht) –

+0

@ArmenTsirunyan ja, das wurde in C++ 0x behoben, die C++ 11 wurde, obwohl die Lösung für '' '' wurde in Abschnitt '14.3' gemacht, was anders als die Korrektur für' <:: 'ist, was eine Modifikation der maximalen viel Regel ist. Also beide nervig aber unterschiedliche Kernthemen bei der Arbeit. Ich erzähle das in meiner Antwort. –

Antwort

33

Nach den Maximal Munch tokenization principle ein gültiger C++ Token/so viele aufeinanderfolgende Zeichen wie möglich sammeln muß.

<: ist eine digraph (eine alternative Darstellung des Symbols [).

      Digraph Equivalent 
           <:   [ 
           :>   ] 
           <%   { 
           %>   } 
           %:   # 

So wird SomeClass<::Class>* cls; als SomeClass[:Class>* cls; interpretiert, die keinen Sinn macht.

Lösung: die folgenden ein Leerzeichen zwischen < und :

SomeClass< ::Class>* cls; 
      ^
      | 
      White Space 
11

Versuchen Sie stattdessen hinzufügen:

SomeClass< ::Class>* cls; 

Sie können weitere Informationen in this Frage zu Digraphe finden. This Frage zu Trigraphs könnte auch hilfreich sein.

2

Put Räume um die < Zeichen:

SomeClass <::Class> * cls; 

Sie brauchen nur tatsächlich < zu trennen und:, aber Ich mag Symmetrie.

+0

plus eins für die Symmetrie – Mawg

7

Mit C++ 11 ändert sich die Antwort auf diese Frage ein wenig.

Pre C++ 11

Zurück zu C 11 ++ die maximal munch rule die lexikalische Analyse verwendet wird, um Mehrdeutigkeiten zu vermeiden und wirkt durch so viele Elemente wie es zu nehmen kann ein gültiges Token dies verursacht bilden:

<: : 

<: ist ein digrap:

<:: 

folgende Token zu erzeugen h, die übersetzt [ und so dass Sie am Ende mit:

SomeClass[:Class>* cls; 

, die nicht gültiger Code ist.

Wir können bestätigen, dass dies der Fall ist, indem auf den Entwurf des C++ Standard Abschnitt gehen 2.4Preprocessing Token die sagt:

Wenn der Eingangsstrom in Vorverarbeitung analysiert wurde zu einer gegebenen Zeichen Tokens bis , das nächste Vorverarbeitungstoken ist die längste Sequenz von Zeichen, die ein Vorverarbeitungstoken bilden könnten, auch wenn , die weitere lexikalische Analyse fehlschlagen würde.

und liefert ein paar Beispiele, einschließlich der folgenden klassischen maximale Munch Frage:

[Beispiel: Die y x +++++ Programmfragment wird analysiert als x ++ ++ + y, , die, wenn x und y von eingebauten Typen sind, eine Beschränkung auf Increment-Operatoren verletzt, auch wenn das Parse x ++ + ++ y einen korrekten Ausdruck ergeben könnte. -Ende Beispiel]

C++ 11

In C++ 11 dieser Änderungen wurde eine Regel für diesen Fall geschnitzt und die draft C++11 standard addierten die folgenden:

Andernfalls Wenn die nächsten drei Zeichen < :: sind und das nachfolgende Zeichen weder: noch> ist, wird < als Präprozessor-Token von selbst behandelt und nicht als erstes Zeichen des alternativen Tokens <:.

Abschnitt 2.5Preprocessing Token. Also wird dieser Code nicht mehr produzieren und Fehler in C++ 11.

Diese Änderung kam von defect report: 1104