类"friend"是否扩展到在该类中声明的类?

Does "friend"ing a class extend to classes declared within that class?

本文关键字:声明 friend 是否 扩展到      更新时间:2023-10-16

我有以下代码,其中类 A 将类 B 声明为朋友。在 B 类中声明的 C 类是否应该能够查看 A 类的私人声明/成员?

它在CL版本16(Visual Studio 2010)中编译时没有错误,但是gcc g++版本4.1.1给出了错误"typedef int A::T在此上下文中是私有的"。

作为 typedefs 的函数调用也会发生相同的行为(这就是我发现差异的方式)。

class A {
   friend class B;
   typedef int T;
};
class B {
   A::T t; // ok
   typedef A::T U; // ok
   class C {
      U u; // ok
      A::T v; // compile error on gcc
   };
};

我已经短暂地查看了一下,但无法找到正确的搜索词。我还没有通读标准。以前是否有关于该主题的问题,或在C++常见问题解答中提到过?标准规定了哪些行为,如果有的话?

来自标准文档,$11.4.2

将一个类声明为朋友意味着授予友谊的类的私人和受保护成员的名称 可以在 befriended 类的基本说明符 s 和成员声明中访问

标准文档中的一个例子,他们自己,

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
    };
};

因此,它应该可以正常工作,没有任何错误。

原始标准 C++03 中似乎存在一些缺陷

根据 C++03 [pre CD1],您的代码不应编译,因为措辞和示例说无法在友元类的嵌套成员中访问类(授予友谊)的私有成员。

C++11给出了与C++03相同的示例。对该示例所做的唯一更改是,友元类的嵌套成员(类)能够访问授予友谊的类的私有成员。

将类声明为好友意味着可以在好友类的基本说明符和成员声明中访问授予友谊的类中的私有和受保护成员的名称。

另请参阅问题 #45

Prasoon提到了问题#45... 此行为在 C++0x 中更改。 旧行为是(第 1 段[class.access.nest] 11.7

):
嵌套类的成员对封闭类

的成员没有特殊访问权限,也没有对已向封闭类授予友谊的类或函数的特殊访问权限。

这清楚地表明,根据 C++03 规则,gcc 4.1 是正确的。 GCC 4.5 和 MSVC2010 使用 C++0X 规则。