Pregunta

Tengo una gran base de código grande que incluye dos espacios de nombres principales: el motor y la aplicación.

El motor define una clase vector3 como un typedef de otra clase vector3, con operadores de igualdad que se ubican en el espacio de nombres del motor, no en la clase vector3. Agregué una clase a la aplicación que también tenía operadores de igualdad en el espacio de nombres de la aplicación.

Cuando intenté compilar, las comparaciones vector3 no relacionadas pero cercanas fallaron porque no pudo encontrar un operador de igualdad apropiado. Sospeché que estaba causando un conflicto, así que moví a mis operadores de igualdad a la clase que agregué, y la compilación tuvo éxito.

// engine.h
namespace Engine
{
    class Vector3Impl { ... };
    typedef Vector3Impl Vector3;
    bool operator==(Vector3 const &lhs, Vector3 const &rhs) { ... }
}


// myfile.cpp
#include "engine.h"

namespace application
{
    class MyClass { ... };
    bool operator==(MyClass const &lhs, MyClass const &rhs) { ... }

    void myFunc(...)
    {
        if ( myClassA == myClassB ) { ... } // builds
    }

    void anotherFunc(...)
    {
        Engine::Vector3 a, b;
        ...
        if ( a == b ) { ... } // fails
    }
}

Sin embargo, después de pensarlo, no puedo ver por qué falló la compilación. No hay conversiones implícitas de vector3s a mi clase o viceversa, y la búsqueda dependiente de argumentos debería extraer el operador de igualdad del espacio de nombres del motor y hacer coincidirlo.

He intentado reproducir este error en un proyecto de C ++ de muestra, pero se niega a romperse. Debe haber algo en la gran base de código grande que está causando este problema, pero no estoy seguro de dónde empezar a buscar. Algo parecido a lo contrario de un pícaro que usa el motor? ¿Alguien tiene alguna idea?

¿Fue útil?

Solución

C ++ Standard, 3.4.4.2 declara:

  

Para cada tipo de argumento T en la llamada a la función, hay un conjunto de cero o más espacios de nombres asociados y un conjunto de cero   o más clases asociadas a considerar. Los conjuntos de espacios de nombres y clases están determinados completamente por los tipos de   los argumentos de la función (y el espacio de nombres de cualquier argumento de plantilla). Nombres de typedef y declaraciones de uso   utilizado para especificar los tipos no contribuyen a este conjunto .

ADL no funciona con typedef's.

Otros consejos

Una vez me encontré con el mismo problema con un compilador que no tenía una búsqueda dependiente de argumentos (Koenig Lookup - gracias @igor) (creo que VC6). Esto significa que cuando ve un operador, solo se ve en los espacios de nombres adjuntos.

Entonces, ¿puedes decirnos qué compilador usas?

Resolverlo en otro compilador lo resolvió

Ciertamente muy inconveniente.

bool operator==(Vector3 const &lhs, Vector3 const &rhs) { ... }

La definición canónica de un operador de igualdad definido en una clase solo debe tener un argumento, a saber, el rhs. El lhs es esto. No sé si esto sería una solución a tu problema, sin embargo.

Esto es lo que escribiría:

clase Vector3 {  operador bool == (const Vector3 & amp; rhs) const {...} };

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top