2010-10-17 12 views
18

Pojawia się błąd <: nie można rozpocząć listy argumentów szablonów w kompilatorze g ++. Kod<: nie można rozpocząć listy argumentów szablonu

template<typename T> class SomeClass; 
class Class; 

SomeClass<::Class>* cls; 
+1

Nowy standrard (C++ 0x) porusza kwestię >> jak w >. Czy nie odnosi się również do tego problemu? Nawiasem mówiąc, kompilatory Micorosoft nie dają tego błędu (wiem, że technicznie powinny, ale dobrze, że nie) –

+0

@ArmenTsirunyan tak, zostało to naprawione w C++ 0x, które stało się C++ 11, chociaż poprawka dla '>>' zostało wykonane w sekcji '14.3', która różni się od poprawki dla' <:: ', która jest modyfikacją reguły maksymalnej. Więc zarówno denerwujące, ale różne podstawowe problemy w pracy. Wyszczególniam to w mojej odpowiedzi. –

Odpowiedz

33

Według Maximal Munch tokenization principle ważny C++ żeton musi zebrać/mieć tyle kolejnych znaków, jak to możliwe.

<: to digraph (alternatywna reprezentacja symbolu [).

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

Więc SomeClass<::Class>* cls; jest interpretowany jako SomeClass[:Class>* cls; który nie ma żadnego sensu.

Rozwiązanie: Dodaj odstępy pomiędzy < i :

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

Wypróbuj następujące zamiast:

SomeClass< ::Class>* cls; 

można znaleźć więcej informacji w this pytanie o digrafach. This pytanie dotyczące trigrafów może być pomocne również.

2

obowiązuje Umieścić wokół < znaków:

SomeClass <::Class> * cls; 

Wystarczy tylko rzeczywiście trzeba oddzielić < i:, ale lubię symetrię.

+0

plus jeden do symetrii sympatia – Mawg

7

W C++ 11 odpowiedź na to pytanie zmienia się nieco.

Pre C++ 11

Poprzednie do C++ 11 maximal munch rule który jest stosowany w analizie leksykalnej, aby uniknąć niejasności i pracuje przyjmując za wiele elementów, jak to możliwe, aby stanowić ważny znak spowodowane w ten sposób:

<:: 

generować następujące znaki jak:

<: : 

<: jest digrap h co przekłada się [ i tak kończy się z:

SomeClass[:Class>* cls; 

który nie jest prawidłowy kod.

Możemy potwierdzić, że jest to przypadek, przechodząc do projektu C++ standardowej sekcji 2.4przerób tokeny który mówi:

Jeśli strumień wejściowy został przeanalizowany pod wyprzedzającym żetony aż do danego znaku , następny token przetwarzania wstępnego to najdłuższa sekwencja znaków, która mogłaby stanowić token przetwarzania wstępnego, nawet jeśli , który spowodowałby niepowodzenie dalszej analizy leksykalnej.

i dostarcza kilka przykładów wraz z następującym klasyczny maksymalnej Munch pytania:

[przykład: Fragment działanie X +++++ y jest analizowany jako x ++ ++ + y, która, jeśli x i y są wbudowanymi typami, narusza ograniczenie na operatorach inkrementujących , nawet jeśli parametr x ++ + ++ y może dać prawidłowe wyrażenie . końcem przykład]

C++ 11

C++ 11 to zmiany, zasada została wykute do tego przypadku i draft C++11 standard dodano następujące:

przeciwnym wypadku , jeśli następne trzy znaki to < ::, a kolejny znak nie jest ani: ani>, to < jest traktowany jako token preprocesora sam, a nie jako pierwszy znak alternatywnego tokena <:.

do sekcji 2.5Przetwarzanie wstępne żetony. Więc ten kod nie będzie już produkować i błąd w C++ 11.

Zmiana ta pochodziła z defect report: 1104