voy a añadir a la respuesta de Jesse sobre el comportamiento aparentemente peculiar de GCC en la compilación:
typedef A<T> A;
vs
typedef ::A<T> A;
Esto también se aplica a la utilización de las declaraciones así de la forma:
using A = A<T>;
using A = ::A<T>;
Lo que parece estar sucediendo dentro de GCC, es que durante la compilación del typedef/u cantar declaración declarando B :: A, que el símbolo B :: A se convierte en un candidato válido dentro de la propia instrucción using. Es decir. cuando dice using A = A<T>;
o typedef A<T> A;
, GCC considera candidatos ::A
y B::A
válidos para A<T>
.
Esto parece un comportamiento extraño porque como su pregunta implica, no espera que el nuevo alias A se convierta en un candidato válido dentro del typedef, pero como también dice Jesse, cualquier cosa declarada dentro de una clase se vuelve visible para todo lo demás dentro de la clase, y en este caso aparentemente incluso la declaración misma. Este tipo de comportamiento se puede implementar de esta manera para permitir definiciones de tipo recursivas.
La solución que encontraste es especificar para GCC con precisión a qué A te refieres dentro del typedef y luego ya no se queja.
Debe ser un nivel de advertencia que por defecto lo muestra como un error. Lo mismo que puede tener una función que falta devolver y se puede informar como un error o advertencia. En general, evitaría declarar el tipo A como A. Será confuso más adelante. –
Grzegorz
No sé lo que dice el estándar, pero estoy feliz de que g ++ se queje ... eso es una tontería. –
Creo que no es tonto ni confuso. Me encuentro con este problema bastante a menudo. En cuanto a la advertencia de la conversión de errores, no le doy ninguna bandera a g ++, ¿qué advertencias convierte en errores por defecto? – foxcub