Si leo correctamente el estándar, g ++ es correcto y VS es incorrecto.
ISO-IEC 14882-2003 (E), §9.2 clases (pag.153): Una clase-nombre se inserta en el ámbito en el que se declara inmediatamente después se ve el nombre de la clase. El nombre de clase también se inserta en el alcance de la clase en sí; esto se conoce como el nombre de clase inyectado. A los efectos de la verificación de acceso, el nombre de la clase inyectada se trata como si fuera un nombre de miembro público.
Tras los comentarios de abajo, también es particularmente útil para retener el siguiente relativa a las normas actuales de búsqueda de nombres:
ISO-IEC 14882 hasta 2.003 (E), §3.4-3 búsqueda de nombres (pag. 29): El nombre de la clase inyectada de una clase (cláusula 9) también se considera miembro de esa clase a los fines del ocultamiento de nombres y la búsqueda.
Sería extraño si no lo fuera, dada la parte final del texto en 9.2. Pero como comentó litb, esto nos asegura que, de hecho, g ++ está haciendo una interpretación correcta del estándar. No quedan preguntas.
Sólo me preguntaba, pero ¿Está utilizando foo y método en tu código real? ¿O solo estás aliasando algún código con el que estabas trabajando? – jkeys
Copié ese código como está en un único proyecto de archivo y agregué una función principal vacía. Esto realmente compila bajo gcc 4.3.3. – Matt
Puedo confirmar que esto realmente compila en g ++ sin advertencias (lo he probado en 3.4.5 mingw) sin espacios de nombres ni nada. Por otro lado MSVC2008 lo rechaza. Muy extraño. –