2010-06-04 18 views
5

Hoy en día uno de mis amigos me dijeron que el código siguiente se compila bien en su Visual Studio 2008:El compilador de Visual C++ permite el nombre dependiente como un tipo sin "nombre de tipo"?

#include <vector> 
struct A 
{ 
    static int const const_iterator = 100; 
}; 
int i; 
template <typename T> 
void PrintAll(const T & obj) 
{ 
    T::const_iterator *i; 
} 
int main() 
{ 
    std::vector<int> v; 
    A a; 
    PrintAll(a); 
    PrintAll(v); 
    return 0; 
} 

lo general el uso g ++, y siempre se niegan a pasar a la segunda llamada Imp todo(). Como sé, para este problema, g ++ está haciendo la forma estándar de traducir una plantilla.

Entonces, ¿está equivocado mi conocimiento, o es una extensión de VS2008?

+0

¿Esto es con/Za (estricto) o/Ze (predeterminado, extensiones)? – MSalters

+0

@MSalters: Lo intenté con/Za hace un momento. No vio ninguna diferencia ... – hpsMouse

Respuesta

8

Esto no es una extensión en absoluto.

VC++ nunca se implementó la interpretación de dos fases correctamente:

  1. En el momento de la definición, analizar la plantilla y determinar todos los nombres no dependientes
  2. En el punto de ejemplificación, compruebe que la plantilla produce válida código

VC++ nunca implementó la primera fase ... es inconveniente ya que significa que no solo acepta código que no es compatible, sino que también produce un código completamente diferente en algunas situaciones.

void foo(int) { std::cout << "int" << std::endl; } 

template <class T> void tfoo() { foo(2.0); } 

void foo(double) { std::cout << "double" << std::endl; } 

int main(int argc, char* argv[]) 
{ 
    tfoo<Dummy>(); 
} 

Con este código:

  • compiladores compatibles imprimirá "int", porque era la única definición disponibles en el momento de la definición de la plantilla y la resolución de foo no depende de T .
  • VC++ imprimirá "doble", ya que nunca se molestó con la fase 1

Podría parecer estúpida por lo que las diferencias van, pero si se piensa en el número de inclusiones que tiene en un programa grande, hay Existe el riesgo de que alguien introduzca una sobrecarga después de su código de plantilla ... y BAM:/

+0

¿Alguna forma de que '' VC++ 'genere una advertencia al menos? Este comportamiento es una molestia para el código que debe funcionar en múltiples compiladores. Los desarrolladores de nuestro equipo se olvidan de agregar la palabra clave de vez en cuando y el código no se puede compilar en 'Clang' – Samaursa

+1

@Samaursa: Desafortunadamente, no que yo sepa. Si está utilizando Clang, puede ser interesante saber que están desarrollando un controlador adicional para VC++, por lo que es posible que pueda invocar Clang directamente desde Visual Studio. –

1

No estoy seguro de que la "extensión" sea exactamente como describiría VC++ a este respecto, pero sí, gcc tiene una mejor conformidad en este sentido.

+0

¿No es este el comportamiento de Visual Studio en modo permisivo? Creo que rechazará el código en modo estricto e implementará esta extensión para compatibilidad con versiones anteriores de VC6. – MSalters

+0

@MSalter: No, VC++ acepta el código incluso con/Za. –

Cuestiones relacionadas