为什么我不能从不同命名空间中的友元类更改类的私有成员?

Jac*_*era 8 c++

我发现从朋友类访问班级的私人成员时遇到问题.

包含我想要更改的私有成员的类以及进行更改的类位于不同的名称空间中.

友元类是在持有数据的类之后定义的,所以我试图在名称空间之外转发声明友元类.

g ++说我无法修改成员,因为它是私有的,视觉工作室似乎认为它很好.

我在这里做一些奇怪的非标准事吗?为什么我不能改变会员?这是一个代表我的问题的简化代码段:

struct S;

namespace N
{
    class A
    {
        int m;
    public:
        A():m(5){};
        friend struct S;
    };

}

using namespace N;

struct S
{
    A& a;
    S(A& a):a(a) {}
    void changeA(){ a.m = 9; }
};

int main()
{
    A a;
    S s(a);
    s.changeA();
}
Run Code Online (Sandbox Code Playgroud)

APr*_*mer 9

friend struct ::S;
Run Code Online (Sandbox Code Playgroud)

你真正在做什么

friend struct S;
Run Code Online (Sandbox Code Playgroud)

正在宣布N :: S类(无处可定义)的朋友.

编辑:支持我的想法,gcc行为是正确的,VC++有一个错误.

7.3.1.2/3

如果friend非本地类中的声明首先声明一个类或函数,那么友元类或函数是最内层封闭命名空间的成员.[...]当查找由朋友声明引入的类或函数的先前声明时,不考虑最内部封闭命名空间作用域之外的作用域.

  • @Jacobo,我的观点是接受你的代码是VC++中的一个错误.(Como和Sun CC都不是我目前访问的另外两个编译器;接受它). (2认同)

Beg*_*oth 5

因为friend struct S;声明N::S类但你需要::S上课.