Title
Class member access referring to an unrelated class
Status
drafting
Section
7.6.1.5 [expr.ref]
Submitter
Jens Maurer

Created on 2022-03-25.00:00:00 last changed 22 months ago

Messages

Date: 2022-04-07.06:59:59

Suggested resolution:

  1. Change in 7.6.1.5 [expr.ref] paragraph 4 as follows:

    Otherwise, the object expression shall be of class type. The class type shall be complete unless the class member access appears in the definition of that class.
    [Note: The program is ill-formed if the result differs from that when the class is complete (6.5.2 [class.member.lookup]). —end note]
    [Note: 6.5.5 [basic.lookup.qual] describes how names are looked up after the . and -> operators. —end note] If E2 is a qualified-id, the terminal name of its nested-name-specifier shall denote the type of E1 or a base class thereof.

    [Example:

      struct A {
        static int x;
      };
    
      struct B {
        static int x;
      };
    
      struct D : B {
        using type = A;
      };
    
      int y1 = D().B::x;         // OK, B is a base class of D
      int y2 = D().type::x;      // error: A is not a base class of D
      int y3 = D::type::x;       // OK, evaluates A::x
    

    end example ]

  2. Change in 7.6.1.5 [expr.ref] bullet 6.5 as follows:

    • ...
    • If E2 is a member an enumerator and the type of E2 is T, the expression E1.E2 is a prvalue. The type of E1.E2 is T.

      [Example:

        enum E { e };
        struct X {
          using E::e;
        };
        int f(X x) {
          return x.e;
        }
      

      end example ]

  3. Change in 7.5.4.1 [expr.prim.id.general] paragraph 3 as follows:

    An id-expression that denotes a non-static data member or non-static member function of a class can only be used:
    • as part of a class member access (7.6.1.5 [expr.ref]) in which the object expression refers to the member's class [ Footnote: ... ] or a class derived from that class, or
    • to form a pointer to member (7.6.2.2 [expr.unary.op]), or
    • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.
Date: 2022-03-25.00:00:00

Consider:

  struct A {
    static int x;
  };

  struct B {
    using type = A;
  };

  int y = B().type::x;

There seems to be no requirement that the member named in a class member access actually is a member of the class of the object expression. Subclause 7.5.4.1 [expr.prim.id.general] paragraph 3 does not cover static members:

An id-expression that denotes a non-static data member or non-static member function of a class can only be used:
  • as part of a class member access in which the object expression refers to the member's class or a class derived from that class, or
  • ...
History
Date User Action Args
2022-06-11 20:21:09adminsetstatus: open -> drafting
2022-03-25 08:36:06adminsetmessages: + msg6778
2022-03-25 00:00:00admincreate