2010-10-17 15 views
18

Aparece un error <: no puedo comenzar una lista de argumentos de plantilla en el compilador g ++. Código<: no puede comenzar una lista de argumentos de plantilla

template<typename T> class SomeClass; 
class Class; 

SomeClass<::Class>* cls; 
+1

El nuevo standrard (C++ 0x) aborda el tema de >> como en un >. ¿No aborda este problema también? Por cierto, los compiladores de Micorosoft no dan error en esto (sé que técnicamente deberían, pero es bueno que no) –

+0

@ArmenTsirunyan sí, esto se corrigió en C++ 0x que se convirtió en C++ 11 aunque la solución para '>>' se realizó en la sección '14.3', que es diferente de la corrección de' <:: ', que es una modificación de la regla máxima. Entonces, tanto problemas centrales molestos como diferentes en el trabajo. Detallo esto en mi respuesta. –

Respuesta

33

De acuerdo con la Maximal Munch tokenization principle un token válido C++ debe recoger/tiene el mayor número de caracteres consecutivos como sea posible.

<: es un digraph (una representación alternativa del símbolo [).

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

Así SomeClass<::Class>* cls; se interpreta como SomeClass[:Class>* cls; que no tiene ningún sentido.

Solución: Añadir un espacio en blanco entre < y :

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

Pruebe lo siguiente en su lugar:

SomeClass< ::Class>* cls; 

Puede encontrar más información en this pregunta sobre dígrafos. This pregunta sobre trigraphs podría ser útil también.

2

espacios poner alrededor de los personajes: <

SomeClass <::Class> * cls; 

Sólo se necesitan realmente para separar y <:, pero me gusta la simetría.

+0

más uno para que le guste la simetría – Mawg

7

Con C++ 11 la respuesta a esta pregunta cambia un poco.

Pre C++ 11

Anterior a C++ 11 la maximal munch rule que se utiliza en el análisis léxico para evitar ambigüedades y funciona tomando tantos elementos como pueda para formar un token válido causó esto:

<:: 

para generar los siguientes tokens como:

<: : 

<: es una digrap h, lo cual se traduce en [ y por lo que terminan con:

SomeClass[:Class>* cls; 

que no es un código válido.

Podemos confirmar que este es el caso, vaya al proyecto de C++ sección estándar 2.4preprocesamiento tokens que dice:

Si el flujo de entrada se ha analizado en el preprocesamiento fichas hasta un carácter dado , el siguiente token de preprocesamiento es la secuencia más larga de caracteres que podrían constituir un token de preprocesamiento, incluso si que causaría que fallara el análisis léxico adicional.

y proporciona un par de ejemplos que incluyen los siguientes máxima clásica pregunta Munch:

[Ejemplo: El fragmento de programa x +++++ y se analiza como x ++ ++ + y, que, si xey son tipos incorporados, infringe una restricción en operadores de incremento, aunque el análisis x ++ + ++ y podría arrojar una expresión correcta . -end ejemplo]

C++ 11

En C++ 11 estos cambios, una regla fue tallada para este caso y el draft C++11 standard añadió la siguiente:

lo contrario , si los siguientes tres caracteres son < :: y el carácter subsiguiente no es: ni>, el < se trata como un token de preprocesador por sí mismo y no como el primer carácter del token alternativo <:.

a la sección 2.5preprocesamiento tokens. Por lo tanto, este código ya no generará errores en C++ 11.

Este cambio vino de defect report: 1104

Cuestiones relacionadas