CWG Issue 45 (original) (raw)

This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 117a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-04-13


45. Access to nested classes

Section: 11.8.8 [class.access.nest]Status: CD1Submitter: Daveed VandevoordeDate: 29 Sep 1998

[Moved to DR at 4/01 meeting.]

Example:

#include <iostream.h>

class C {  // entire body is private
    struct Parent {
        Parent() { cout << "C::Parent::Parent()\n"; }
    };

    struct Derived : Parent {
        Derived() { cout << "C::Derived::Derived()\n"; }
    };

    Derived d;
};


int main() {
    C c;      //  Prints message from both nested classes
    return 0;
}

How legal/illegal is this? Paragraphs that seem to apply here are:

11.8 [class.access] paragraph 1:

A member of a class can be

and 11.8.8 [class.access.nest] paragraph 1:

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 (11.8 [class.access] ) shall be obeyed. [...]

This makes me think that the ': Parent' part is OK by itself, but that the implicit call of 'Parent::Parent()' by 'Derived::Derived()' is not.

From Mike Miller:

I think it is completely legal, by the reasoning given in the (non-normative) 11.8.8 [class.access.nest] paragraph 2. The use of a private nested class as a base of another nested class is explicitly declared to be acceptable there. I think the rationale in the comments in the example ("// OK because of injection of name A in A") presupposes that public members of the base class will be public members in a (publicly-derived) derived class, regardless of the access of the base class, so the constructor invocation should be okay as well.

I can't find anything normative that explicitly says that, though.

(See also papers J16/99-0009 = WG21 N1186, J16/00-0031 = WG21 N1254, and J16/00-0045 = WG21 N1268.)

Proposed Resolution (04/01):

  1. Insert the following as a new paragraph following 11.8 [class.access] paragraph 1:

    A member of a class can also access all names as the class of which it is a member. A local class of a member function may access the same names that the member function itself may access. [_Footnote:_Access permissions are thus transitive and cumulative to nested and local classes.]

  2. Delete 11.8 [class.access] paragraph 6.
  3. In 11.8.8 [class.access.nest] paragraph 1, change

    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 (11.8 [class.access]) shall be obeyed.
    to
    A nested class is a member and as such has the same access rights as any other member.
    Change
    B b; // error: E::B is private
    to
    B b; // Okay, E::I can access E::B
    Change
    p->x = i; // error: E::x is private
    to
    p->x = i; // Okay, E::I can access E::x

  4. Delete 11.8.8 [class.access.nest] paragraph 2.

(This resolution also resolves issues8 and10.