friend declared function call

Discussion in 'C++' started by Sven Köhler, Apr 11, 2008.

  1. Sven Köhler

    Sven Köhler Guest

    Hi,

    so i have some strange class declaration, which looks like this:


    namespace wurst {
    class bla {
    friend bool foobla(const bla& v, int x) {
    return true;
    }
    };
    }


    With this, the following code works:

    wurst::bla foo;
    foobla(foo, 2);


    How do i access foobla in a more specific way? What the "full qualified
    name" of foobla?

    The following alternatives DON'T work:

    wurst::foobla(foo,2)
    wurst::bla::foobla(foo, 2);

    Can you give a working alternative?


    Regards,
    Sven
     
    Sven Köhler, Apr 11, 2008
    #1
    1. Advertising

  2. Sven Köhler

    Christopher Guest

    On Apr 10, 7:16 pm, Sven Köhler <> wrote:
    > Hi,
    >
    > so i have some strange class declaration, which looks like this:
    >
    > namespace wurst {
    > class bla {
    > friend bool foobla(const bla& v, int x) {
    > return true;
    > }
    > };
    >
    > }



    Someone got confused there.
    A friend function shouldn't be implemented in the class it is a friend
    of. Otherwise, it wouldn't be a friend, but a method belonging to the
    class instead.

    I would expect something like:

    namespace wurst
    {
    class bla
    {
    friend bool foobla(const bla & v, int x);

    int m_value;

    public:
    bla(int value)
    :
    m_value(value)
    {}
    };

    bool foobla(const bla & v, int x)
    {
    // Access to private data of bla is allowed because of frienship
    if( x = bla.m_value )
    {
    return true;
    }
    }
    }

    and for it to be called like so:

    wurst::bla foo(2);
    bool result = wurst::foobla(foo, 2);

    Where being a friend function gives the function "foobla" access to
    "bla"'s private data.
     
    Christopher, Apr 11, 2008
    #2
    1. Advertising

  3. Sven Köhler

    Ian Collins Guest

    Christopher wrote:
    > On Apr 10, 7:16 pm, Sven Köhler <> wrote:
    >> Hi,
    >>
    >> so i have some strange class declaration, which looks like this:
    >>
    >> namespace wurst {
    >> class bla {
    >> friend bool foobla(const bla& v, int x) {
    >> return true;
    >> }
    >> };
    >>
    >> }

    >
    >
    > Someone got confused there.
    > A friend function shouldn't be implemented in the class it is a friend
    > of. Otherwise, it wouldn't be a friend, but a method belonging to the
    > class instead.
    >

    That simply isn't true. A friend has to be declared and may also be
    defined within the class definition.

    Two classic examples are I/O operators and callback functions which
    require extern C linkage.

    --
    Ian Collins.
     
    Ian Collins, Apr 11, 2008
    #3
  4. Sven Köhler

    Ian Collins Guest

    Sven Köhler wrote:
    > Hi,
    >
    > so i have some strange class declaration, which looks like this:
    >
    >
    > namespace wurst {
    > class bla {
    > friend bool foobla(const bla& v, int x) {
    > return true;
    > }
    > };
    > }
    >

    Nothing particularly strange about that.

    >
    > With this, the following code works:
    >
    > wurst::bla foo;
    > foobla(foo, 2);
    >

    OK.
    >
    > How do i access foobla in a more specific way? What the "full qualified
    > name" of foobla?
    >
    > The following alternatives DON'T work:
    >
    > wurst::foobla(foo,2)


    This is OK.

    > wurst::bla::foobla(foo, 2);
    >

    This isn't. foobla() isn't a member of bla (this form would be used if
    foobla() were a static member function).

    --
    Ian Collins.
     
    Ian Collins, Apr 11, 2008
    #4
  5. Sven Köhler

    Ian Collins Guest

    Christopher Pisz wrote:
    > "Ian Collins" <> wrote in message
    > news:...
    >> Christopher wrote:
    >>> Someone got confused there.
    >>> A friend function shouldn't be implemented in the class it is a friend
    >>> of. Otherwise, it wouldn't be a friend, but a method belonging to the
    >>> class instead.
    >>>

    >> That simply isn't true. A friend has to be declared and may also be
    >> defined within the class definition.
    >>
    >> Two classic examples are I/O operators and callback functions which
    >> require extern C linkage.

    >
    > Show example code please. I've searched my I/O libraries and cannot find the
    > keyword friend anywhere, so you must be talking of custom operators, and
    > then I still cannot fathom why the function wouldn't be a plain old class
    > method.
    >

    The output and input operators << and >> are often declared as free
    functions, which may be friends of the class.

    --
    Ian Collins.
     
    Ian Collins, Apr 11, 2008
    #5
  6. Sven Köhler

    Sven Köhler Guest

    >> The following alternatives DON'T work:
    >>
    >> wurst::foobla(foo,2)

    >
    > This is OK.


    No, it isn't. (At least, if it isn't a gcc bug)

    gcc says something like "no member foobla in wurst".
     
    Sven Köhler, Apr 11, 2008
    #6
  7. Sven Köhler

    Sven Köhler Guest

    >>> The following alternatives DON'T work:
    >>>
    >>> wurst::foobla(foo,2)

    >>
    >> This is OK.

    >
    > No, it isn't. (At least, if it isn't a gcc bug)
    >
    > gcc says something like "no member foobla in wurst".


    OK, minimal non-compiling example:

    namespace wurst {
    class bla {
    friend bool foobla(const bla& v, int x) {
    return true;
    }
    };
    }

    int main()
    {
    wurst::bla foo;
    wurst::foobla(foo, 2);
    return 0;
    }


    LANG=C g++ test.cpp gives:
    test.cpp: In function 'int main()':
    test.cpp:12: error: 'foobla' is not a member of 'wurst'
     
    Sven Köhler, Apr 11, 2008
    #7
  8. Sven Köhler

    James Kanze Guest

    On Apr 11, 3:20 am, Ian Collins <> wrote:
    > Sven Köhler wrote:


    > > so i have some strange class declaration, which looks like this:


    > > namespace wurst {
    > > class bla {
    > > friend bool foobla(const bla& v, int x) {
    > > return true;
    > > }
    > > };
    > > }


    > Nothing particularly strange about that.


    > > With this, the following code works:


    > > wurst::bla foo;
    > > foobla(foo, 2);


    > OK.


    Yes. ADL kicks in, and finds the function declared in scope
    wurst::foo.

    > > How do i access foobla in a more specific way? What the
    > > "full qualified name" of foobla?


    Strictly speaking, it's worst::foobla.

    > > The following alternatives DON'T work:


    > > wurst::foobla(foo,2)


    > This is OK.


    Not without some additional code. As written, the name foobla
    is declared in the scope wurst::bla, and is only visible in this
    scope. Despite the fact that the fully qualified name is
    wurst::foobla, the name is not visible in the scope wurst. And
    ADL doesn't apply to qualified names, so the compiler cannot
    find the name.

    For this to work, there must be a declaration:

    namespace wurst {
    extern bool foobla( bla const& v, int x ) ;
    }

    somewhere before this use.

    > > wurst::bla::foobla(foo, 2);


    > This isn't. foobla() isn't a member of bla (this form would
    > be used if foobla() were a static member function).


    The problem, of course, is that the scope and the qualification
    don't agree, and that in the case of qualified name lookup, the
    compiler requires both to match. When it looks the function up
    in wurst::, it doesn't find it, because the declaration is not
    in scope. And when it looks the name up in wurst::bla, it sees
    the function, but doesn't consider it, because if the
    qualification names a class, only class members (or members of
    base classes) are considered.

    It's not particularly intuitive, but that's the way it is. In
    general, if a function is designed to work with a specific type
    of object, don't qualify it, and count on ADL.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 11, 2008
    #8
  9. Sven Köhler

    James Kanze Guest

    On Apr 11, 3:16 am, Ian Collins <> wrote:
    > Christopher wrote:
    > > On Apr 10, 7:16 pm, Sven Köhler <> wrote:


    > >> so i have some strange class declaration, which looks like this:


    > >> namespace wurst {
    > >> class bla {
    > >> friend bool foobla(const bla& v, int x) {
    > >> return true;
    > >> }
    > >> };
    > >> }


    > > Someone got confused there.
    > > A friend function shouldn't be implemented in the class it is a friend
    > > of. Otherwise, it wouldn't be a friend, but a method belonging to the
    > > class instead.


    > That simply isn't true. A friend has to be declared and may
    > also be defined within the class definition.


    It's actually a fairly standard idiom for operators in general
    (although it may be applied for normal functions as well). In a
    lot of cases, in fact, the friend declaration is present not
    because the function requires access to private members, but
    because it allows definition in the class. The standard Barton
    and Nackman trick, for example. (I use it regularly for
    generating the binary operators from the <op>= forms, for
    example. Or for generating a complete STL iterator interface
    from a small set of iterator primitives.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 11, 2008
    #9
  10. Sven Köhler

    Sven Köhler Guest

    > For this to work, there must be a declaration:
    >
    > namespace wurst {
    > extern bool foobla( bla const& v, int x ) ;
    > }
    >
    > somewhere before this use.


    Works for me!

    Thanks for explaining! Really saved my day.
     
    Sven Köhler, Apr 11, 2008
    #10
  11. Sven Köhler

    Markus Moll Guest

    Hi

    Sven Köhler wrote:

    > namespace wurst {
    > class bla {
    > friend bool foobla(const bla& v, int x) {
    > return true;
    > }
    > };
    > }


    Defining a friend function inside a class is a bit weird. However, it's
    allowed. The difference to defining it outside the class (as far as I can
    see) is that it is in the scope of the class, it is not visible outside the
    class and it is implicitly inline.

    This means that you have to declare it in the surrounding namespace if you
    want to use it there, and you don't have to qualify class members inside
    the definition.

    > How do i access foobla in a more specific way? What the "full qualified
    > name" of foobla?


    It is <namespace>::f, but it is not visible.

    > The following alternatives DON'T work:
    >
    > wurst::foobla(foo,2)


    Would be correct if you had previously declared wurst::foobla:

    namespace wurst // the wurst possible name ;-)
    {
    bool foobla(const bla& v, int x);
    }

    > wurst::bla::foobla(foo, 2);


    Definitely not.

    Markus
     
    Markus Moll, Apr 11, 2008
    #11
  12. Sven Köhler

    Christopher Guest

    On Apr 11, 12:07 am, Ian Collins <> wrote:
    > Christopher Pisz wrote:
    > > "Ian Collins" <> wrote in message
    > >news:...
    > >> Christopher wrote:
    > >>> Someone got confused there.
    > >>> A friend function shouldn't be implemented in the class it is a friend
    > >>> of. Otherwise, it wouldn't be a friend, but a method belonging to the
    > >>> class instead.

    >
    > >> That simply isn't true. A friend has to be declared and may also be
    > >> defined within the class definition.

    >
    > >> Two classic examples are I/O operators and callback functions which
    > >> require extern C linkage.

    >
    > > Show example code please. I've searched my I/O libraries and cannot find the
    > > keyword friend anywhere, so you must be talking of custom operators, and
    > > then I still cannot fathom why the function wouldn't be a plain old class
    > > method.

    >
    > The output and input operators << and >> are often declared as free
    > functions, which may be friends of the class.
    >
    > --
    > Ian Collins.


    I've never seen those implemented _inside_ the class, but defined and
    implemented outside the class and then made a friend of the class.
     
    Christopher, Apr 11, 2008
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JohnZing

    declared or not declared ?

    JohnZing, Feb 5, 2006, in forum: ASP .Net
    Replies:
    3
    Views:
    1,608
    Jon Paal
    Feb 5, 2006
  2. csudha

    Reg virtual function and friend function

    csudha, Feb 20, 2005, in forum: C Programming
    Replies:
    5
    Views:
    317
    infobahn
    Feb 21, 2005
  3. Replies:
    11
    Views:
    585
  4. Jeff
    Replies:
    2
    Views:
    110
  5. Peter
    Replies:
    2
    Views:
    287
    Öö Tiib
    Jun 6, 2013
Loading...

Share This Page