2010-09-14 7 views
5

He encontrado este extraño caso de código (a continuación) no compila bajo Visual Studio 2008 y produce un "error C2872: 'Ambigüedad': símbolo ambiguo" en la línea 12.VS2008 (+?) Error del compilador con funciones de plantilla y 'using namespace'

Extracción del uso de namespace RequiredNamespace en la última línea fija el error, pero yo esperaría que poner using namespace al final de un archivo no debe tener efecto. También se basa en que AnotherFunction es una función de plantilla, por lo que espero que el compilador esté generando las funciones de plantilla en el ámbito incorrecto o que no restablezca la lista de espacios de nombres que se utilizan antes de hacerlo.

El mismo código se compila en GCC.

Ambos compiladores parecen generar el código para TemplatedFunction después de la definición using namespace Namespace, al menos hasta donde puedo decir, al introducir errores y observar el orden en que se envían.

namespace Ambiguity 
{ 
    class cSomeClass 
    { 
    }; 

    template<class T> 
    void TemplatedFunction(T a) 
    { 
     // this is where the error occurs, the compiler thinks Ambiguity 
     // might refer to the class in RequiredNamespace below 
     Ambiguity::cSomeClass(); 
    } 
} 

namespace RequiredNamespace 
{ 
    // without a namespace around this class, the Ambiguity class 
    // and namespace collide 
    class Ambiguity 
    { 
    }; 
} 

int main() 
{ 
    // to force the templated function to be generated 
    Ambiguity::TemplatedFunction(4); 
} 

// removing this removes the error, but it shouldn't really do anything 
using namespace RequiredNamespace; 

Obviamente, esto es un ejemplo manufacturado, pero el original se extrae de un caso real en el que el using namespace se encuentra en un archivo generado automáticamente producido por código de tercera parte.

¿Esto es un error en el compilador?

+1

¿soy yo o es este un ejemplo realmente difícil de leer, con estos identificadores particulares? –

+0

Preet: no es solo usted. –

+0

¿Cómo puedo hacerlo más simple?Supongo que parte del problema es que si se siguieran las convenciones de nomenclatura, el problema no ocurriría; si prefijaras tus clases con c, por ejemplo, no tendrías una clase llamada Ambigüedad. Lo he ajustado un poco. – eAi

Respuesta

2

Creo que es un error, por 7.3.4 párrafo 1 de la norma C++ 03:

A usando directiva especifica que los nombres en el espacio de nombres nominados se pueden utilizar en el ámbito en el que la directiva de uso aparece después de la directiva de uso.

Por lo tanto, su declaración de fin de archivo no debería tener ningún efecto.

5

Acepto que es un error, pero se puede obtner una idea de lo que está pasando generando la lista de ensamblaje correspondiente a su archivo (use la opción/Fa de cl.exe).

Por lo tanto, comente la declaración de uso, genere el archivo .asm y ábralo en un editor de texto. Escanee el archivo y puede ver que la creación de instancias de la plantilla está en la parte inferior del archivo (comienza con [email protected]@[email protected]@[email protected] PROC), y está debajo del ensamblaje generado para la función principal (comienza con _main PROC). El mensaje de error decía "ver referencia a la instanciación de la plantilla de función", por lo que se refiere a la creación de instancias de la función de plantilla, y la lista de ensamblaje deja en claro que esta instanciación se encuentra en la parte inferior del archivo.

Ahora, edite el código para reemplazar la función de plantilla con NonTemplatedFunction(int a) y compile, generando una lista de ensamblaje. Vea la lista de ensambles y verá que el código de ensamblado generado para NonTemplatedFunction(int a) aparece arriba de _main PROC.

¿Qué significa todo este parloteo? Cuando el compilador de Visual Studio 2008 convierte sus plantillas en código real, de hecho agrega algún código al final de su archivo después de usar la declaración. Su declaración de uso significa que los nombres en el código generado automáticamente son "ambiguos". El proceso que usa gcc para crear instancias de plantillas obviamente evita este problema.

+0

+1: Si lo cambió a una función sin plantilla, Intellisense se quejará pero el archivo se compilará. – Puppy

Cuestiones relacionadas