12

What is the difference between doing:

struct A;
struct B { friend struct A; };

and

struct A;
struct B { friend A; };

What does it mean to leave out struct in the second part?

Anton Savin
  • 40,838
  • 8
  • 54
  • 90
Walter
  • 123
  • 1
  • 1
  • 4
  • Nothing whatsoever, given the snippets you've provided. – Sneftel Oct 23 '14 at 22:15
  • 1
    As for the second code snippet, I wanted to say `#define A void foobar(int,double)` but the preceding forward declaration of `struct A;` invalidates that (half-)joke. Eh. – quetzalcoatl Oct 23 '14 at 22:17
  • In case you don't agree with the title change I proposed, feel free to reedit. I just thought that the original title sounded more like .. teen peer-support forum :| Maybe that's just me today.. – quetzalcoatl Oct 23 '14 at 22:20
  • @quetzalcoatl `#define A A; void foobar(int,double)` – Sneftel Oct 23 '14 at 22:24

1 Answers1

18

The difference is that if you write friend A;, A must be a known type name, that is it must be declared before.

If you write friend struct A;, this itself is a declaration of A, so no prior declaration is needed:

struct B { friend struct A; }; // OK

There are several subtleties though. For example, friend class/struct A declares class A in innermost enclosing namespace of class B (thanks to Captain Obvlious):

class A;
namespace N {
    class B {
        friend A;         // ::A is a friend
        friend class A;   // Declares class N::A despite prior declaration of ::A,
                          // so ::A is not a friend if previous line is commented
    };
}

Also there are several other cases when you can write only friend A:

  1. A is a typedef-name:

    class A;
    typedef A A_Alias;
    
    struct B {
        // friend class A_Alias;  - ill-formed
        friend A_Alias;
    };
    
  2. A is a template parameter:

    template<typename A>
    struct B { 
        // friend class A;  - ill-formed
        friend A;
    };
    
Community
  • 1
  • 1
Anton Savin
  • 40,838
  • 8
  • 54
  • 90