Question

J'ai une grande base de code qui comprend deux espaces de noms principaux: le moteur et l'application.

Le moteur définit une classe vector3 en tant que typedef d'une autre classe vector3, avec des opérateurs d'égalité situés dans l'espace de noms du moteur et non dans la classe vector3. J'ai ajouté à l'application une classe qui comportait également des opérateurs d'égalité dans l'espace de noms de l'application.

Lorsque j'ai essayé de compiler, les comparaisons de vecteur 3 non apparentées mais proches ont échoué car elles ne pouvaient pas trouver d'opérateur d'égalité approprié. Je pensais que j'étais à l'origine d'un conflit, j'ai donc transféré mes opérateurs d'égalité dans la classe que j'ai ajoutée et la compilation a réussi.

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

Cependant, après y avoir réfléchi, je ne vois pas pourquoi la compilation a échoué. Il n'y a pas de conversions implicites de vector3 dans ma classe ou inversement, et la recherche dépendante des arguments devrait extraire l'opérateur d'égalité de l'espace de noms du moteur et le faire correspondre.

J'ai essayé de reproduire ce bogue dans un exemple de projet C ++, mais cela ne fonctionne pas. Il doit y avoir quelque chose dans la grande base de code qui cause ce problème, mais je ne sais pas par où commencer. Quelque chose comme l'opposé d'un voyou qui utilise "Engine"? Quelqu'un a des idées?

Était-ce utile?

La solution

La norme C ++, 3.4.4.2 déclare:

  

Pour chaque type d'argument T dans l'appel de fonction, il existe un ensemble de zéro ou plusieurs espaces de nom associés et un ensemble de zéro.   ou plusieurs classes associées à prendre en compte. Les ensembles d’espaces de noms et de classes sont entièrement déterminés par les types de   les arguments de la fonction (et l'espace de noms de tout argument de modèle). Noms de typedef et using-declarations   utilisé pour spécifier les types ne contribuent pas à cet ensemble .

L'ADL ne fonctionne pas avec le typedef.

Autres conseils

Un jour, j’ai rencontré le même problème avec un compilateur qui n’avait pas de fonction de recherche dépendante des arguments (Koenig Lookup - merci @igor) (VC6, je pense). Cela signifie que lorsqu'il voit un opérateur, il ne fait que regarder dans les espaces de noms qui les entourent.

Alors pouvez-vous nous dire quel compilateur vous utilisez?

Le passage à un autre compilateur a résolu le problème.

Très peu pratique en effet.

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

La définition canonique d'un opérateur d'égalité défini sur une classe ne devrait avoir qu'un seul argument, à savoir le rhs. La lhs est la suivante. Je ne sais pas si ce serait une solution à votre problème cependant.

Voici ce que j'écrirais:

classe Vector3 {  opérateur bool == (const Vector3 & rhs) const {...} };

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top