2010-05-05 14 views
5

Al experimentar un poco con las plantillas de C++ me las arreglé para producir este código simple, para el cual el resultado es diferente, de lo que esperaba de acuerdo con mi comprensión de las reglas de C++.Búsqueda de nombre para nombres que no dependen del parámetro de plantilla en VC++ 2008 Express. ¿Es un error?

void bar(double d) 
{ 
    std::cout << "bar(double) function called" << std::endl; 
} 

template <typename T> void foo(T t) 
{ 
    bar(3); 
} 

void bar(int i) 
{ 
    std::cout << "bar(int) function called" << std::endl; 
} 

int main() 
{ 
    foo(3); 
    return 0; 
} 

Cuando puedo compilar el código en VC++ 2008 Express, la función se llama a bar(int). Ese sería el comportamiento, esperaría si bar(3); en el cuerpo de la plantilla dependiera del parámetro de la plantilla. Pero no lo es. La regla que encontré here dice "El estándar de C++ prescribe que todos los nombres que no dependen de los parámetros de la plantilla están vinculados a sus definiciones actuales al analizar una función o clase de plantilla". ¿Estoy equivocado, esa "definición actual" de bar al analizar la función de plantilla foo es la definición de void bar(double d);? Por qué no es el caso si estoy equivocado. No hay declaraciones directas de bar en esta unidad de compilación.

+0

No le sorprendería que usted tenga razón. Me parece que la implementación de plantillas de VC++ ignora completamente los problemas dependientes/no dependientes. – UncleBens

+1

VC++ nunca respetó la evaluación estándar de 2 pases (la primera al leer la definición de la plantilla y la segunda en la instanciación de la plantilla). Guarda la escritura 'typename' y' template' en algunos lugares pero ... no es compatible. –

+0

En aras de la precisión, se refiere a la sección 14.6.3 Nombres no dependientes [temp.nondep] del Estándar. (Borrador final) – Francesco

Respuesta

3

De hecho es un error en el compilador. Se sabía que el problema existía en VS2005 y antes (uso un blog de Blogspot como un cuaderno para casos como este, vea 1.3 here). Aparentemente también está presente en VS2008.

Puede probarlo con el siguiente código simple

int bar(double d) { return 0; } 

template <typename T> void foo(T t) { 
    int i = bar(3); 
} 

void bar(int i); 

int main() { 
    foo(3); 
} 

está bien formado Este código (se puede compilar con el compilador Comeau en línea), pero apuesto a que VS se ahogue en él porque VS implementa el búsqueda bifásica incorrectamente en este caso.

+0

Sí, VS (bueno, al menos mi versión Express, pero creo que es el mismo compilador en otros) afirma que hay errores en el código. Gracias. –

+0

Este error aún aparece en Visual Studio 2010. – smerlin

2

AndreyT es correcto. De hecho, su código es prácticamente idéntico a un ejemplo del estándar (§14.6.3/1):

void g(double); 
void h(); 

template<class T> class Z { 
public: 
    void f() { 
     g(1); //calls g(double) 
     h++;  //ill-formed: cannot increment function; 
       // this could be diagnosed either here or 
       // at the point of instantiation 
    } 
}; 

void g(int);  // not in scope at the point of the template 
       // definition, not considered for the call g(1) 
Cuestiones relacionadas