Thread: Finding friends

  1. #1
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99

    Finding friends

    I am trying to decipher the following paragraph from chapter 11.5.1 of Bjarne Stroustrup's The C++ Programming Language:

    "A friend class must be previously declared in an enclosing scope or defined in the non-class scope immediately enclosing the class that is declaring it a friend. Scopes outside the innermost enclosing namespace scope are not considered."

    The following compliles and runs fine with Code::Blocks GCC, so I presume that the word "previously" relates only to "declared" and not to "defined", since the definition of class Y comes after that of class X:

    Code:
    #include <iostream>
    
    using namespace std;
    
    namespace out
    {
    class X
    {
        int i;
        public:
        X(int j = 0):i(j){}
        friend class Y;
    };
    
     class Y
    {
        public:
        void f(X x){cout << x.i;}
    };
    
    }
    
    int main()
    {
        out::X x(101);
        out::Y y;
        y.f(x);
    }
    Likewise, the following compliles and runs fine with the same compiler, so I presume the second sentence relates only to definition and not to declaration, since the declaration of class Y is outside the innermost enclosing namespace and yet it is evidently being considered:

    Code:
    #include <iostream>
    
    using namespace std;
    
    class Y;
    
    namespace out
    {
    class X
    {
        int i;
        public:
        X(int j = 0):i(j){}
        friend class Y;
    };
    }
    
     class Y
    {
        public:
        void f(out::X x){cout << x.i;}
    };
    
    int main()
    {
        out::X x(101);
        Y y;
        y.f(x);
    }
    To sum up, I would interpret the text to mean the following:

    A friend class must be declared previously in an enclosing scope or defined somewhere in the non-class scope immediately enclosing the class that is declaring it a friend. In the latter case, scopes outside the innermost namespace scope or not considered.

    Is that right?
    Last edited by DL1; 07-28-2009 at 08:50 AM.

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    137
    Really, who writes this stuff? Sounds worse than my physics textbook.

    I recommend just reading several different website's tutorials on friend classes to get a better idea. Sometimes books can have sections that are vague or hard to understand.
    ★ Inferno provides Programming Tutorials in a variety of languages. Join our Programming Forums. ★

  3. #3
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92
    Quote Originally Posted by execute View Post
    Really, who writes this stuff? Sounds worse than my physics textbook.

    I recommend just reading several different website's tutorials on friend classes to get a better idea. Sometimes books can have sections that are vague or hard to understand.
    Granted that book is a bit dry, I think the writer knows what he's talking about, since he created C++.
    IDE + Complier: Code::Blocks w/ GCC
    PC: AMD Phenom x4 2.2Ghz w/ 8G RAM
    OSes: CentOS 6.2 x64 & Win 7 Ultimate x64

  4. #4
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    I actually don't find it that dry; the author even makes the odd joke in places, which is more than can be said for e.g. K&R.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Friends are very, very weird.

    Code:
    namespace ns {
      class X { friend void fn(X&); };
    }
    This interesting snippet has the following effects:
    1) Declare and define a namespace 'ns'.
    2) Declare and define a class 'ns::X'.
    3) Declare a function 'ns::fn(ns::X&)' that is a friend of 'ns::X'. However, the declaration is special in that the compiler doesn't find it with normal name lookup, i.e. if the compiler works correctly, this should fail to compile:
    Code:
    int main()
    {
      ns::X x;
      ns::fn(x); // error: ns::fn not found
    }
    However, the function can be found via argument-dependent lookup:
    Code:
    int main()
    {
      ns::X x;
      fn(x); // works
    }
    This is the case for names (functions and classes) that are unknown prior to the friend declaration.
    Now consider this case:

    Code:
    class A;
    namespace ns {
      class B;
      class X {
        class D;
    
        friend class A; // references ::A
        friend class B; // references ns::B
        friend class C; // hidden-declares and references ns::C
        friend class D; // references ns::X::D
      };
    
      class C {}; // defines ns::C, which is a friend of ns::X
      class A {}; // declares and defines ns::A, which has no relation to ns::X
    }
    class A {}; // defines ::A, which is a friend of ns::X
    class C {}; // declares and defines ::C, which has no relation to ns::X
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    Jun 2008
    Location
    Somewhere in Europe
    Posts
    99
    Code:
    ns::fn(x); // error: ns::fn not found
    gcc does seem to find ns::fn() even if it's not supposed to (it also finds fn() with the unqualified call using argument-dependent lookup).

    If fn() really is in namespace 'ns', why shouldn't it be found with the qualified call?
    Last edited by DL1; 08-03-2009 at 03:50 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. tools for finding memory leaks
    By stanlvw in forum C++ Programming
    Replies: 4
    Last Post: 04-03-2009, 11:41 AM
  2. Finding primes
    By starripper in forum C++ Programming
    Replies: 19
    Last Post: 01-14-2006, 04:17 PM
  3. Finding parents in a general tree
    By neandrake in forum C++ Programming
    Replies: 4
    Last Post: 03-22-2005, 08:19 PM
  4. finding an element in a linked list from the end.
    By anoopks in forum C Programming
    Replies: 9
    Last Post: 04-08-2004, 09:00 AM
  5. MFC :: Finding Child Window of a CWnd* Object?
    By SyntaxBubble in forum Windows Programming
    Replies: 2
    Last Post: 09-06-2003, 09:06 AM