Pergunta

Eu tenho uma grande base de código grande que inclui dois espaços principais: o motor ea aplicação.

O motor define uma classe Vector3 como um typedef de outra classe Vector3, com operadores de igualdade que se sentam no espaço de nomes do motor, não na classe Vector3. Eu adicionei uma classe para o aplicativo que também tinha operadores de igualdade no espaço de nomes da aplicação.

Quando eu tentei compilar, não relacionado, mas quase por Vector3 comparações falhou porque não conseguiu encontrar o operador de igualdade apropriado. Eu suspeitava que estava causando um conflito tão comovido meus operadores de igualdade para a classe I adicionado, e a compilação sucedido.

// 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
    }
}

No entanto, depois de pensar sobre isso eu não posso ver porque a compilação falhou. Não existem conversões implícitas de vector3s a minha classe, ou vice-versa, e look-up argumento-dependente deve ser a puxar para o operador de igualdade a partir do namespace motor e combinando-o.

Eu tentei reproduzir este bug em um projeto de exemplo C ++, mas que se recusa a quebrar. Deve haver algo na grande base de código grande que está causando esse problema, mas eu não tenho certeza de onde começar a procurar. Algo como o oposto de um rogue "usando Motor"? Alguém tem alguma idéia?

Foi útil?

Solução

C ++ Padrão, 3.4.4.2 declara:

Para cada tipo de argumento T na chamada de função, há um conjunto de zero ou namespaces mais associados e um conjunto de zero, ou classes a serem considerados mais associado. Os conjuntos de namespaces e classes é inteiramente determinado pelos tipos de os argumentos da função (e o namespace de qualquer argumento modelo modelo). nomes typedef e usando-declarações usado para especificar os tipos não contribuem para este conjunto .

ADL não funciona com typedef de.

Outras dicas

Uma vez eu corri para o mesmo problema com um compilador que não tinha argumento Dependente Lookup (Koenig Lookup - graças @igor) (VC6 eu acho). Isto significa que quando vê um operador, ele só olha nos namespaces que encerram.

Então, você pode nos dizer o que compilador você usa?

Passar para outro compilador resolveu.

Muito inconveniente, de fato.

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

A definição canônica de um operador de igualdade definido em uma classe deve ter apenas um argumento, ou seja, os RHS. A LHS é este. Não sei se isso seria uma solução para o seu problema embora.

Isto é o que eu iria escrever:

classe Vector3 { bool operator == (const Vector3 & rhs) const {...} };

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top