friend + namespace



  • warum geht das nicht?

    struct foo{
    	foo(int) { }
    };
    
    class bar;
    
    namespace some
    {
    	foo fun(const bar& t);
    }
    
    class bar {
    	int member = 10;
    public:
    	friend foo ::some::fun(const bar&); // Error: foo is not a type
    };
    
    foo some::fun(const bar& t) {
    	return t.member;
    }
    
    int main() {
    	bar b;
    	some::fun(b);
    }
    

    wenn ich den rückgabetyp von fun auf int wähle, kompiliert es anstandslos

    😕


  • Mod

    foo ::some::fun
    

    Ist äquivalent zu

    foo::some::fun
    

    Leerzeichen zwischen Operatoren sind i.d.R. wegzudenken (das ist natürlich nur grob gemeint!).
    foo wird hier als Teil des nested-name-specifiers angesehen. Nicht als der Rückgabetyp.

    Eine Lösung wäre es natürlich den globalen Scope-Operator zu entfernen

    friend foo some::fun(const bar&);
    

  • Mod

    andere Möglichkeiten

    friend foo (::some::fun(const bar&));
    friend auto ::some::fun(const bar&) -> foo;
    


  • Danke und tschö



  • wenn ich den rückgabetyp von fun auf int wähle, kompiliert es anstandslos

    Der Rückgabetyp von

    foo some::fun(const bar& t)
    

    ist foo aber nicht int. Du gibts aber mit t.member einen int zurück!



  • Keksman schrieb:

    wenn ich den rückgabetyp von fun auf int wähle, kompiliert es anstandslos

    Der Rückgabetyp von

    foo some::fun(const bar& t)
    

    ist foo aber nicht int. Du gibts aber mit t.member einen int zurück!

    Aber int kann implizit in einen foo umgewandelt werden.



  • bumerangtyp schrieb:

    Aber int kann implizit in einen foo umgewandelt werden.

    ARgg. Sorry ich wollte eigentlich nur helfen.



  • camper schrieb:

    andere Möglichkeiten

    friend foo (::some::fun(const bar&));
    

    Huch?
    Nicht

    friend foo (::some::fun)(const bar&);
    

    ?


  • Mod

    hustbaer schrieb:

    camper schrieb:

    andere Möglichkeiten

    friend foo (::some::fun(const bar&));
    

    Huch?
    Nicht

    friend foo (::some::fun)(const bar&);
    

    ?

    so geht es auch.



  • Seit wann kann man da denn Klammern hinsetzen? Das ist doch keine expression. Gibts dafuer irgendwo eine spezielle Regel?



  • Ich dachte mir halt, wenns bei typedef so geht, wieso sollte es dann bei friend nicht gehen?

    typedef int (*FunctionPtr)();
    

    Die Schreibweise von camper kannte ich aber auch noch nicht.

    Funktionsnamen klammern ist auch eine gute Möglichkeit um die Auswertung als Function-Style-Makro zu verhindern:

    #define max(a, b) ((a) > (b) ? (a) : (b))
    
    //int x = std::max(foo(), bar());
    int x = (std::max)(foo(), bar());
    

  • Mod

    Kellerautomat schrieb:

    Seit wann kann man da denn Klammern hinsetzen? Das ist doch keine expression. Gibts dafuer irgendwo eine spezielle Regel?

    Du kannst vieles in Klammern setzen.

    int(a);
    

    Solltest du kennen, oder?

    Lässt sich auf

    §8.3/4 schrieb:

    In a declaration T D where D has the form
    ( D1 )
    the type of the contained declarator-id is the same as that of the contained declarator-id in the declaration
    T D1
    Parentheses do not alter the type of the embedded declarator-id, but they can alter the binding of complex declarators.

    zurückführen.



  • Arcoth schrieb:

    Du kannst vieles in Klammern setzen.

    int(a);
    

    Solltest du kennen, oder?

    Noe. Bzw, jetzt schon. Wasn Mist.


Anmelden zum Antworten