c++ - puede - paso de parametros por referencia en c
<: no puede comenzar una lista de argumentos de plantilla (4)
Recibo un error <: no puedo comenzar una lista de argumentos de plantilla en el compilador g ++. Código
template<typename T> class SomeClass;
class Class;
SomeClass<::Class>* cls;
Con C ++ 11 la respuesta a esta pregunta cambia un poco.
Pre C ++ 11
Antes de C ++ 11, la regla de munch máxima que se usa en el análisis léxico para evitar ambigüedades y funciona tomando tantos elementos como sea posible para formar un token válido causado por esto:
<::
para generar los siguientes tokens como:
<: :
<:
es un dígrafo que se traduce en [
y así terminas con:
SomeClass[:Class>* cls;
Que no es un código válido.
Podemos confirmar que este es el caso yendo al borrador de la sección 2.4
estándar C ++ Preprocesamiento de tokens que dice:
Si el flujo de entrada se ha analizado en tokens de preprocesamiento hasta un carácter determinado, el siguiente token de preprocesamiento es la secuencia más larga de caracteres que podrían constituir un token de preprocesamiento, incluso si eso causara que un análisis léxico adicional falle.
y proporciona un par de ejemplos que incluyen la siguiente pregunta de munch máxima clásica:
[Ejemplo: el fragmento de programa x +++++ y se analiza como x ++ ++ + y, que, si xey son de tipos incorporados, viola una restricción en los operadores de incremento, aunque el parse x + + + ++ y podría producir una expresión correcta. —En ejemplo]
C ++ 11
En C ++ 11 esto cambia, se elaboró una regla para este caso y el borrador de la norma C ++ 11 agregó lo siguiente:
De lo contrario, si los siguientes tres caracteres son <:: y el siguiente no es ni: 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.5
Fichas de preprocesamiento . Entonces, este código ya no producirá un error en C ++ 11.
Este cambio vino de informe de defectos: 1104
De acuerdo con el principio de tokenización de Maximal Munch, un token de C ++ válido debe recopilar / tener tantos caracteres consecutivos como sea posible.
<:
es un digraph (una representación alternativa del símbolo [
).
Digraph Equivalent
<: [
:> ]
<% {
%> }
%: #
Entonces SomeClass<::Class>* cls;
se interpreta como SomeClass[:Class>* cls;
Lo que no tiene ningún sentido.
Solución: agregue un espacio en blanco entre <
y :
SomeClass< ::Class>* cls;
^
|
White Space
Pon espacios alrededor de los <caracteres:
SomeClass < ::Class > * cls;
Solo necesitas separar <y:, pero me gusta la simetría.