2011-04-15 7 views
6

En this question, el autor de la pregunta tiene la siguiente función:¿Por qué no se necesita typename _not_ aquí en Visual Studio 2008/2010?

template<typename ITER> 
bool nextPermutation(ITER start, ITER end) 
{ 
    return nextPermutation(start, end, std::iterator_traits<ITER>::iterator_category()); 
} 

¿Por qué no es un typename necesaria antes de la std::iterator_traits? Pensé que era necesario para los tipos anidados de una plantilla, si la plantilla depende de un parámetro de plantilla en sí mismo. GCC parece apoyar mi idea, ya que no se compila bajo 4.3.4 y 4.5.1, exigiendo un typename. Aún así, todavía se compila muy bien tanto en Visual Studio 2008 como en 2010.
¿Es esta otra extensión/error de Visual Studio que no conozco?
¿O es realmente posible deducir que iterator_category es un tipo o una función porque es seguido por un par de paréntesis ()? (Consulte los mensajes de @ DeadGM starting here.) Entonces, ¿esto es realmente un error en GCC?

+0

Además de las opciones que enumera (constructor y función), 'iterator_category' podría ser una variable de miembro estática de un tipo que define operator(). – Sjoerd

+0

@Sjoerd: O un puntero a la función. – sbi

Respuesta

6

¿MSVC no implementa el esquema de análisis tardío? En tal esquema, el compilador no depende de typename. Simplemente almacena todos los tokens entre las llaves de la definición de la plantilla, y cuando se crea una instancia de la plantilla, analiza esos tokens. Como sabe qué es y qué no es un tipo, funcionará sin typename.

Pero si el compilador no diagnostica la falta typename al crear una instancia de la plantilla, entonces no es conforme.

¿O es realmente posible deducir que iterator_category es un tipo o una función porque es seguido por un par de paréntesis()?

Todo lo que importa es si el nombre es dependiente y calificado. No importa si la plantilla puede deducirse a sí misma que el nombre es siempre un tipo. Sin embargo, podría importar la calidad de los mensajes de error por falta de typename s.

FWIW, no, no es posible deducir nada sobre iterator_category en un nivel de idioma.

+0

Tenga en cuenta que el diagnóstico requerido puede ser solo una advertencia. Así que mientras el compilador emita al menos una advertencia, se permite "compilar muy bien". En segundo lugar, esa advertencia podría desactivarse de manera predeterminada: todos los compiladores que conozco requieren una bandera u opción para estar presentes para seguir el estándar de C++ lo más cerca posible: al actualizar un compilador, la mayoría de los clientes no desean nuevos avisos/errores para su código anterior, por lo que la compatibilidad con versiones anteriores obliga a los escritores del compilador a ocultar nuevos errores detrás de las opciones adicionales. – Sjoerd

+0

@Sjoerd: la norma siempre solo habla de "diagnósticos". Eso podría ser errores o advertencias, cualquiera estaría bien. – sbi

+0

@sbi Estoy seguro de que tú y Johannes lo saben, pero no es de conocimiento común. – Sjoerd

11

Es bien conocido que Visual C++ no admite completamente la búsqueda en dos fases, que es la razón subyacente de por qué se requiere typename en primer lugar. Si el compilador no admite completamente esto, es posible que no analice por completo una plantilla antes de que se cree una instancia, momento en el cual "sabe" que std::iterator_traits<ITER>::iterator_category es un tipo. Obviamente, esta deficiencia se extiende a VC10.

Cuando se trata de typename, confío en GCC sobre VC cualquier día.

+0

Respuesta perfectamente completa, pero voy a responder a @Johannes, ya que explica un poco más sobre el último análisis. +1 sin embargo. :) – Xeo

Cuestiones relacionadas