friend-injection



  • Hallo,

    ich habe gerade folgendes gefunden:

    ARM-style name-injection of friend declarations is no longer the default. For example:

    struct S {
    friend void f();
    };

    void g() { f(); }

    will not be accepted; instead a declaration of f will need to be present outside of the scope of S. The new -ffriend-injection option will enable the old behavior.

    Das fette verstehe ich nicht. Was muss ich tun?

    Gruß
    Boris



  • Hallo,
    friend beinhalted immer auch eine Deklaration eines Namens. Eine solche Deklaration kann entweder die erste Deklaration eines Namens sein oder aber eine vorhandene Deklaration wiederholen.
    Wenn es die erste Deklaration ist (wie hier), wird der Name immer im über der Klasse liegenden Namensraum (hier der globale) deklariert. Man spricht hier von "friend name injection". Die Frage ist nun, wie bzw. ob ein solch injizierter Name sichtbar ist. Früher war ein injizierter Name ganz normal sichtbar, deshalb hätte dein Beispiel funktioniert (g kann f verwenden, da ein f im globalen Namensraum existiert). Später hat man aber festgellt, dass dies besonders im Zusammenhang mit Templates problematisch wird -> durch die Instanziierung von Templates werden auf einmal Namen von normalen Funktionen sichtbar.
    Aus diesem Grund bleiben injizierte Namen in Standard-C++ unsichtbar und damit nicht über normlen Name-Lookup aufrufbar. Dein Beispiel funktioniert also nicht, da in der Funktion g keine Funktion f bekannt ist.
    Die Lösung wäre hier auf eine bereits vorhandene Deklaration zurückzugreifen:

    void f();
    struct S {
    friend void f(); // Redeklaration von ::f
    };
    
    void g() {  
      f(); // ok
    }
    

    PS: Es gibt allerdings noch eine Ausnahme: durch Friend-Deklarationen injizierte Namen können über Argument-Dependent-Name-Lookup gefunden werden.

    So würde dein Beispiel also funktionieren:

    struct S {
    friend void f(S*);
    };
    
    void g() { 
      S* s; 
      f(s); // wird über ADL-gefunden
    }
    

Anmelden zum Antworten