TITLE: Nested classes, friends, and statics PROBLEM: [ A programmer was having trouble with nested classes, friends, and static members. The original code is not here, but the responses cover most of it. -adc ] RESPONSE: p j l @cs.uiuc.edu (Paul Lucas) [A] Try this: class E { private: class inner; friend class inner; static inner* innertable; class inner { public: inline inner* get() { return E::innertable; } }; }; For get(), you have to say *what* innertable. [B] You have to reverse the "class inner;" and friend declarations otherwise the friend grants access to some class named inner at file-scope (since it hasn't been seen yet). [C] This works under cfront 3.0; I forget where ANSI is on this; I know they were fi[dd]ling with the rules for friend declarations in classes recently. RESPONSE: jamshid@emx.cc.utexas.edu (Jamshid Afshar), 19 Jan 93 [A] I don't think the ARM requires a qualifier when using 'innertable' in get(), though a buggy compiler might require it and the ARM allows redundant scope qualifiers. See r9.7. A nested class's member function is in the scope of its enclosing class, though it has no special access rights to the enclosing class (unless it is made a friend as in this example). [B] Correct. This should fix the first (correct) error Thomas was getting that "innertable" is not accessible in get(). Actually, I just checked the original article and the error was that "inner" was not accessible in get(). Does DEC C++ think a class's member function does not have access to its own class, or did Thomas miscopy the error? [C] Yes, they are, but I don't think they're changing the scope rules of nested classes (just friend functions). The other error Thomas was getting was for the static member definition of E::innertable. I have been told the intentions of the ARM are that: E::inner* E::innertable = 0; // static member def; ARM error is illegal because 'E::inner' is not accessible at file-scope. I have also been told ANSI is considering allowing the use of non-public nested types in file-scope when defining static data members or member functions. This will make non-public nested types more useful since you would otherwise not be able to use them for static members or as the return type of member functions defined outside the class. I believe ANSI will make this change, so go ahead and file a bug report if your compiler doesn't accept: class E { private: class inner; friend class inner; static inner* innertable; class inner { public: inner* get() { return innertable; } }; }; E::inner* E::innertable = 0; // you must qualify 'inner', though older C++ rules // put 'inner' in global scope and the by-definition equivalent version with get() declared inline and defined inline immediately following the class. Btw, BC++ 3.1 accepts it but has some problems with non-public nested typedefs and enums. [...]