3

The following code compiles on MSVC:

#include <iostream>

class Bob
{        
    int a;
    friend class Outer;
};
class Outer
{      
    class Inner
    {
        void f(Bob obj)
        {
            std::cout << obj.a; //OK
        }
    };
};

So it seems that if Outer is a friend of Bob, so is Inner, automatically. I am reading the Friends chapter of the standard and am unable to find a clause that would confirm or refute this.

Is this legal, and if so, what's the chapter and verse?

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • [This](http://stackoverflow.com/questions/5013717/are-inner-classes-in-c-automatically-friends) seems to answer the question. *A member of a class can also access all the names to which the class has access* – NathanOliver Mar 21 '17 at 11:53
  • 2
    Possible duplicate of [Are inner classes in C++ automatically friends?](http://stackoverflow.com/questions/5013717/are-inner-classes-in-c-automatically-friends) – Jonas Mar 21 '17 at 11:56
  • 1
    @Jonas: That question talks about the fact that private members of class Outer are accessible from Inner, which I am aware of. This question is very different, don't you think? – Armen Tsirunyan Mar 21 '17 at 11:57
  • I do not think so. It states that the nested class can access all the names available to the outer class. That means the nested class can access the members of classes the outer class is friends of since the outer class has access to those names. – NathanOliver Mar 21 '17 at 11:59

1 Answers1

3

[class.access.nest]/1 states that

A nested class is a member and as such has the same access rights as any other member

So I believe yes, this is standard behavior.

Let's say that Outer has a member function foo(). That function, of course, will have access to Bob's members. To my understanding, the part that I quoted implies that any nested class inside Outer would have the same access rights as foo(), thus having the ability to access Bob's members.

It is also worth noting that the standard contains the following example ([class.friend]/2), note the usage of A::B in Y:

class A {
    class B { };
    friend class X;
};

struct X : A::B {
    // OK: A::B accessible to friend
    A::B mx; // OK: A::B accessible to member of friend
    class Y {
        A::B my; // OK: A::B accessible to nested member of friend
    };
};
SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105