Domanda

Ho una grande base di codice che include due spazi dei nomi principali: il motore e l'applicazione.

Il motore definisce una classe vector3 come un typedef di un'altra classe vector3, con operatori di uguaglianza che si trovano nello spazio dei nomi del motore, non nella classe vector3. Ho aggiunto una classe all'applicazione che aveva anche operatori di uguaglianza nello spazio dei nomi dell'applicazione.

Quando ho provato a compilare, i confronti di vector3 non correlati ma vicini non sono riusciti perché non è stato possibile trovare un operatore di uguaglianza appropriato. Sospettavo di causare un conflitto, quindi ho spostato i miei operatori di uguaglianza nella classe che ho aggiunto e la compilazione è riuscita.

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

Tuttavia, dopo averci pensato, non riesco a capire perché la compilazione non è riuscita. Non ci sono conversioni implicite da vector3s alla mia classe o viceversa e la ricerca dipendente dall'argomento dovrebbe trascinare l'operatore di uguaglianza dallo spazio dei nomi del motore e abbinarlo.

Ho provato a riprodurre questo bug in un progetto C ++ di esempio ma questo si rifiuta di rompersi. Ci deve essere qualcosa nella grande base di codice che sta causando questo problema, ma non sono sicuro da dove cominciare a cercare. Qualcosa di simile al contrario di una canaglia "usando il motore"? Qualcuno ha qualche idea?

È stato utile?

Soluzione

C ++ Standard, 3.4.4.2 dichiara:

  

Per ogni argomento di tipo T nella chiamata di funzione, esiste un set di zero o più spazi dei nomi associati e un set di zero   o più classi associate da prendere in considerazione. Gli insiemi di spazi dei nomi e classi sono determinati interamente dai tipi di   gli argomenti della funzione (e lo spazio dei nomi di qualsiasi argomento del modello di modello). Nomi dattiloscritti e dichiarazioni di utilizzo   utilizzato per specificare i tipi non contribuisce a questo set .

ADL non funziona con typedef's.

Altri suggerimenti

Una volta mi sono imbattuto nello stesso problema con un compilatore che non aveva Argument Dependent Lookup (Koenig Lookup - thanks @igor) (VC6 credo). Ciò significa che quando vede un operatore, appare solo negli spazi dei nomi racchiusi.

Quindi puoi dirci quale compilatore usi?

Il passaggio a un altro compilatore ha risolto il problema.

Davvero molto scomodo.

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

La definizione canonica di un operatore di uguaglianza definita su una classe dovrebbe avere solo un argomento, vale a dire rhs. Questo è questo. Non so se questa sarebbe una soluzione al tuo problema.

Questo è ciò che vorrei scrivere:

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top