The current C++ standard (C++03) has the following restriction that would make your code ill-formed:
The members of a nested class have no special access to members of an enclosing class, nor to classes or functions that have granted friendship to an enclosing class; the usual access rules shall be obeyed (C++03 11.8/1).
However, this rule has been reversed in the forthcoming C++ standard (C++0x). The paragraph now reads:
A nested class is a member and as such has the same access rights as any other member. The members of an enclosing class have no special access to members of a nested class; the usual access rules shall be obeyed (C++0x Draft N3225 11.8/1).
So, under the old interpretation, your code is incorrect but under the new interpretation it is correct. This is basically a defect in the original C++ Standard; the defect was noted in 1998 and the correction was agreed to in 2001. You can find details on that in CWG Defect 45.
Note that regardless which interpretation you want to use, I think there is still a bug in the compiler. The following is the minimal repro, and generates the same error when using Visual C++ 2010:
class A {
protected:
void f() { }
};
struct D {
struct B : A {
struct C {
void g() {
B().f();
}
};
};
};
However, if you remove D
and put B
in the global namespace, the compiler accepts the code.