name lookup happens before type checking problem



  • Ich habe eine free function mit der signatur

    namespace bla{
    void draw(std::string s){ }
    

    und eine Klasse

    struct Foo{
    
    friend void draw(int i){}
    };
    }
    

    jetzt versuche ich in einem anderen file draw aufzurufen mit einem Foo Objekt als Argument

    bla::draw(Foo{});
    

    allerdings matched der compiler mir den function call mit der free function. Meine Frage ist, was ich tun kann damit die friend function stattdessen aufgerufen wird. Diese ist ja keine member function von Foo und ich wüsste gerne, wie das geht.

    Danke schon einmal


  • Mod

    std::int
    

    ?

    #include <iostream>
    #include <string>
    
    void f(std::string) { std::cout << "string\n"; }
    struct foo {
        friend void f(foo) {std::cout << "foo\n"; }
    };
    
    int main() {
        f(foo{});
    }
    

    gibt foo aus.


  • Mod

    friend Funktionen, die nicht noch separat in namespace scope deklariert wurden, können nur über ADL gefunden werden, d.h. einer der Argumente muss vom Typ der befreundeten Klasse sein. Dabei ist es sogar unwichtig, welche genauen Typen die Parameter haben, solange die Konvertierung wohlgeformt ist:

    struct foo {
        friend void f(int) {std::cout << "foo\n"; }
        operator int();
    };
    
    int main() {
        f(foo{});
    }
    

    Ich bezweifle also, dass der gezeigte Code der ist, der dich beschäftigt.


  • Mod

    Arcoth schrieb:

    friend Funktionen, die nicht noch separat in namespace scope deklariert wurden, können nur über ADL gefunden werden, d.h. einer der Argumente muss vom Typ der befreundeten Klasse sein. Dabei ist es sogar unwichtig, welche genauen Typen die Parameter haben, solange die Konvertierung wohlgeformt ist:

    ??

    Es genügt wenn der Typ eines der Argumente, bzw. soweit anwendbar eine Basisklasse oder eines der Templateargumente - mit der Klasse assoziert sind.

    #include <iostream>
    #include <string>
    
    void f(std::string) { std::cout << "string\n"; }
    struct bar;
    struct foo {
        friend void f(const bar&) {std::cout << "bar\n"; }
        struct baz { operator bar&(); };
    };
    struct bar : foo {};
    foo::baz::operator bar&() { static bar x; return x; }
    
    template <typename T> struct foobar { operator bar() { return {}; }; };
    int main() {
        f(bar{});
        f(foo::baz{});
        f(foobar<bar>{});
    }
    


  • doch genau der code ist mein Problem oO


  • Mod

    Sewing schrieb:

    struct Foo{
     
    friend void draw(int i){}
    };
    

    ➡

    struct Foo{
    
    friend void draw(int i){}
    };
    void draw(int i);
    

  • Mod

    camper schrieb:

    Arcoth schrieb:

    friend Funktionen, die nicht noch separat in namespace scope deklariert wurden, können nur über ADL gefunden werden, d.h. einer der Argumente muss vom Typ der befreundeten Klasse sein. Dabei ist es sogar unwichtig, welche genauen Typen die Parameter haben, solange die Konvertierung wohlgeformt ist:

    ??

    Es genügt wenn der Typ eines der Argumente, bzw. soweit anwendbar eine Basisklasse oder eines der Templateargumente - mit der Klasse assoziert sind.

    Ja, sorry, da artikuliert man sich einmal unpräzise um den TE nicht zu überfordern... 🙄



  • ja so habe ich mir auch beholfen, allerdings erscheint es mir seltsam, nach einer definition noch eine deklaration zu verwenden


  • Mod

    @Sewing: Dein Problem ist der qualifizierte Name.

    draw(bla::Foo{});
    

    camper schrieb:

    Sewing schrieb:

    struct Foo{
     
    friend void draw(int i){}
    };
    

    ➡

    struct Foo{
     
    friend void draw(int i){}
    };
    void draw(int i);
    

    ???
    :p


  • Mod

    Arcoth schrieb:

    Ja, sorry, da artikuliert man sich einmal unpräzise um den TE nicht zu überfordern... 🙄

    Solche Tage hast du also auch ... :p

    Arcoth schrieb:

    ???
    :p

    Löst das Problem des TE, soweit ich sehe.


Anmelden zum Antworten