Namespace aus ADL Lookup entfernen?



  • Hi,

    ich habe folgendes Problem:

    namespace A{//kann ich nicht ändern
        class Foo(){};
    
        void doSomething(Foo const& foo);//eine Funktion die nicht macht, was ich will.
    
    };
    
    namespace B{//kann ich nicht ändern
        template<class T>
        void doSomething(T const& t);//die Funktion die macht, was ich will
    };
    
    namespace C{//kann ich ändern
        class Foo2:public Foo(){};//Ich muss von Foo erben.
    };
    
    namespace D{//kann ich nicht ändern
        class Foo3(){};
    
        void doSomething(Foo3 const& foo);//muss via ADL gefunden werden
    
    };
    
    template<class T>
    int myFunction(T const& t){
        using B::doSomething;//enable lookup of B::doSomthing via ADL
        doSomething(t);
    };
    
    D::Foo3 a;
    C::Foo2 b;
    doSomething(a);//funktioniert
    doSomething(b);//ruft A::doSomething auf :(
    

    Kann ich verhindern, dass nach A::doSomething gesucht wird? Ich bin hier gerade Opfer von suboptimalen Library design (boost::begin vs boost::fusion::begin )



  • Aufruf qualifizieren?
    Ansonsten bitte kompilierbaren Code posten, damit man das Problem nachvollziehen kann.



  • Na ja, du kannst in C doSomething überladen, das sollte dann bevorzugt werden, dann musst du nur einmal B:: schreiben.



  • Ich glaube, ein Kommentar ist falsch:

    otze schrieb:

    namespace A{//kann ich nicht ändern
        class Foo(){};
    
        void doSomething(Foo const& foo);//eine Funktion die nicht macht, was ich will.
    
    };
    
    namespace B{//kann ich nicht ändern
        template<class T>
        void doSomething(T const& t);//die Funktion die macht, was ich will
    };
    
    namespace C{//kann ich ändern
        class Foo2:public Foo(){};//Ich muss von Foo erben.
    };
    
    namespace D{//kann ich nicht ändern
        class Foo3(){};
    
        void doSomething(Foo3 const& foo);//muss via ADL gefunden werden
    
    };
    
    template<class T>
    int myFunction(T const& t){
        using B::doSomething;//enable lookup of B::doSomthing via ADL
        doSomething(t);
    };
    

    Ich denke, das sollte heißen

    template<class T>
    int myFunction(T const& t){
        using B::doSomething; // Using-Deklaration von B::doSomthing
        doSomething(t);       // unqualifiziert, damit auch
                              // D::doSomething per ADL gefunden wird
    };
    

    denn B::doSomething kann nie per ADL gefunden werden, weil in B gar kein benutzerdefinierter Typ definiert wurde.

    otze schrieb:

    D::Foo3 a;
    C::Foo2 b;
    doSomething(a);//funktioniert
    doSomething(b);//ruft A::doSomething auf :(
    

    Kann ich verhindern, dass nach A::doSomething gesucht wird? Ich bin hier gerade Opfer von suboptimalen Library design (boost::begin vs boost::fusion::begin )

    Hmmm... komisch. Ich hätte gedacht, dass B::doSomething im zweiten Fall ein besserer Match als A::doSomething wäre. Da ist ja immerhin eine Foo2*->Foo* Konvertierung bei.

    Und sonst: siehe cooky451s Beitrag.


  • Mod

    krümelkacker schrieb:

    Ich denke, das sollte heißen

    template<class T>
    int myFunction(T const& t){
        using B::doSomething; // Using-Deklaration von B::doSomthing
        doSomething(t);       // unqualifiziert, damit auch
                              // D::doSomething per ADL gefunden wird
    };
    

    denn B::doSomething kann nie per ADL gefunden werden, weil in B gar kein benutzerdefinierter Typ definiert wurde.

    korrekt. Allerdings wird B::doSomething so über normales unqualifiziertes Lookup gefunden.

    krümelkacker schrieb:

    otze schrieb:

    D::Foo3 a;
    C::Foo2 b;
    doSomething(a);//funktioniert
    doSomething(b);//ruft A::doSomething auf :(
    

    Kann ich verhindern, dass nach A::doSomething gesucht wird? Ich bin hier gerade Opfer von suboptimalen Library design (boost::begin vs boost::fusion::begin )

    Hmmm... komisch. Ich hätte gedacht, dass B::doSomething im zweiten Fall ein besserer Match als A::doSomething wäre. Da ist ja immerhin eine Foo2*->Foo* Konvertierung bei.

    Und sonst: siehe cooky451s Beitrag.

    B::doSomething kann ja gerade nicht gefunden werden, weil B kein assoziierter Namensraum ist (s.o.).

    Eine using-Deklaration in C sollte helfen.

    namespace C{
        using ::B::doSomething;
    }
    


  • camper schrieb:

    B::doSomething kann ja gerade nicht gefunden werden, weil B kein assoziierter Namensraum ist (s.o.).

    Upps. Ich habe den Code im falschen Kontext betrachtet. Hatte immer noch diese using-Deklaration im Kopf.


Anmelden zum Antworten