friend ohne class ISO-konform



  • Hiho,

    ich habe eine kurze Frage zu friend-Deklarationen.

    Ich kanne das bisher immer so:

    friend class CDdeString;
    

    Nun hatte ich gerade den Fall, dass ich ein Friend auf einen typedef von unique_ptr wollte:

    friend struct std::unique_ptr<CDdeService>::deleter_type;
    

    Das meckert der Compiler an, folgendes schluckt er aber:

    friend std::unique_ptr<CDdeService>::deleter_type;
    

    Ist das ISO-konform? Bezogen auf das erste Beispiel geht auch ohne Warnung nun ein

    friend CDdeString;
    

    Oder ist das eine Compiler-Erweiterung?

    VG

    Pellaeon



  • Das meckert der Compiler an

    Wie heisst die Fehlermeldung? Was ist, wenn deleter_type kein struct ist?



  • Pellaeon schrieb:

    Bezogen auf das erste Beispiel geht auch ohne Warnung nun ein

    friend CDdeString;
    

    Oder ist das eine Compiler-Erweiterung?

    diese Deklaration ist gültig, wenn class CDdeString vorher schon deklariert wurde. bei

    friend class CDdeString;
    

    wird
    1. class CDdeString im äußeren Scope forward deklariert und
    2. CDdeString wird ein friend der eigenen Klasse



  • Also sind folgende 2 Codeschnippsel äquivalent?

    namespace ns
    {
        class foo;
        class bar
        {
            friend foo;
        };
    }
    

    und

    namespace ns
    {
        class bar
        {
            friend class foo;
        };
    }
    


  • jo



  • das scheint nicht identisch zu sein

    3.3.2 Point of declaration
    10 [ Note: Friend declarations refer to functions or classes that are members of the nearest enclosing namespace, but they do not introduce new names into that namespace (7.3.1.2). Function declarations at block scope and variable declarations with the extern specifier at block scope refer to declarations that are members of an enclosing namespace, but they do not introduce new names into that scope. —end note ]

    7.3.1.2 Namespace member definitions
    3 Every name first declared in a namespace is a member of that namespace. If a friend declaration in a nonlocal class first declares a class or function95 the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by unqualified lookup (3.4.1) or by qualified lookup (3.4.3) until a matching declaration is provided in that namespace scope (either before or after the class definition granting friendship).



  • dd++ schrieb:

    3.3.2 Point of declaration
    10 [ Note: [...] —end note ]

    Der Inhalt von Note ist nie normgebend.

    Deshalb hast du richtig formuliert, es "scheint nicht identisch zu sein".


  • Mod

    C++03 schrieb:

    11.4 Friends
    /3
    ...
    An elaborated-type-specifier shall be used in a friend declaration for a class.

    C++11 schrieb:

    11.3 Friends
    3 A friend declaration that does not declare a function shall have one of the following forms:
    friend elaborated-type-specifier ;
    friend simple-type-specifier ;
    friend typename-specifier ;
    [ Note: A friend declaration may be the declaration in a template-declaration (Clause 14, 14.5.4).—end
    note ] If the type specifier in a friend declaration designates a (possibly cv-qualified) class type, that class
    is declared as a friend; otherwise, the friend declaration is ignored. [ Example:
    class C;
    typedef C Ct;
    class X1 {
    friend C; // OK: class C is a friend
    };
    class X2 {
    friend Ct; // OK: class C is a friend
    friend D; // error: no type-name D in scope
    friend class D; // OK: elaborated-type-specifier declares new class
    };
    template <typename T> class R {
    friend T;
    };
    R<C> rc; // class C is a friend of R<C>
    R<int> Ri; // OK: "friend int;" is ignored
    —end example ]

    Mit anderen Worten: in C++11 macht es keinen Unterschied, ob class explizit verwendet wird, sofern beide Varianten überhaupt zulässig sind. Ohne class muss der entsprechende Bezeichner bereits zuvor deklariert worden sein.


Anmelden zum Antworten