4
#include <iostream>
#include <string>

class A {
    friend class B;
    std::string m = "Hello";
};

struct B {
    struct N {
        void f(){
            A a;
            std::cout << a.m << std::endl;
        };
    };
};

int main() {
    B::N().f();
}

Is N allowed to access m?

EDIT

Okay I ran it in cpp.sh and obviously it works. Is there a generic rule to understand how friendship relations are obtained?

ManuelSchneid3r
  • 15,850
  • 12
  • 65
  • 103
  • 2
    You know you can simply put your code sample in a compiler and see for yourself, right? –  Aug 03 '17 at 15:06
  • 1
    Have you tried it? Did you get conflicting results that made you ask this? – underscore_d Aug 03 '17 at 15:06
  • I think this is ultimately a duplicate: [Are inner classes in C++ automatically friends?](https://stackoverflow.com/questions/5013717/are-inner-classes-in-c-automatically-friends) key words: `A nested class is a member and as such has the same access rights as any other member.` So, just as members (functions and data) of `B` have `friend` access to `A`, so does `N`, because it too is a member. – underscore_d Aug 03 '17 at 15:09
  • Nope not related. The friendship in question is not between an inner and outer class. The friendship is between the top level classes. I just want to understand how friendship is "distibuted". How is friendship bound? The scope? – ManuelSchneid3r Aug 03 '17 at 15:12
  • It _is_ related for the reason I quoted. `N` is a member of `B`, so just as methods (which are also members) of `B` can access members of `A`, so can your method in `N`. – underscore_d Aug 03 '17 at 15:13
  • So it is the scope that determines the friendship? – ManuelSchneid3r Aug 03 '17 at 15:14
  • @Frank: The result of one trial doesn't tell you the general rule, and besides, compilers don't always match the standards as closely as they should, so just because something compiles now doesn't mean it always will. – Arthur Tacca Aug 03 '17 at 15:56

1 Answers1

8

The standard is pretty clear that friendship is not inherited:

14.3/10: "Friendship is neither inherited nor transitive"

But a nested class is not inheritance. It is a member. If a class is a friend, its members have access to the class's friends. Therefore, the inner/nested class has access.

Straight from the standard:

14.3/2 Declaring a class to be a friend implies that the names of private and protected members from the class granting friendship can be accessed in the base-specifiers and member declarations of the befriended class. Example:

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
    };
};
Chris Uzdavinis
  • 6,022
  • 9
  • 16