Non-dependent references to base class members
13.8.3 [temp.dep]
Mike Miller

Created on 2005-04-18.00:00:00 last changed 162 months ago


Date: 2006-10-15.00:00:00

[Voted into WP at the October, 2006 meeting.]

Date: 2005-10-15.00:00:00

Proposed resolution (October, 2005):

Change 11.4.3 [class.mfct.non-static] paragraph 3 as indicated:

When an id-expression (_N4567_.5.1.1 [expr.prim.general]) that is not part of a class member access syntax ( [expr.ref]) and not used to form a pointer to member ( [expr.unary.op]) is used in the body of a non-static member function of class X or used in the mem-initializer for a constructor of class X, if name lookup (6.5.3 [basic.lookup.unqual]) resolves the name in the id-expression to a non-static non-type member of class X or of a base class of X some class C, the id-expression is transformed into a class member access expression ( [expr.ref]) using (*this) (_N4868_. [class.this]) as the postfix-expression to the left of the . operator. [Note: If C is not X or a base class of X, the class member access expression is ill-formed. —end note] The member name then refers to the member of the object for which the function is called. Similarly during name lookup...
Date: 2007-09-09.00:00:00

Implementations vary in their treatment of the following code:

    struct A {
      int foo_;
    template <typename T> struct B: public A { };
    template <typename T> struct C: B<T> {
      int foo() {
        return A::foo_;  // #1
    int f(C<int>* p) {
      return p->foo();

According to one analysis, because the expression A::foo_ on line #1 is non-dependent, it must be analyzed in the definition context. It that context, it violates the restrictions of 11.4 [class.mem] paragraph 10 on how the name of a nonstatic data member of a class can be used and thus should be treated as an error.

On the other hand, the description of the transformation of an id-expression into a class member access expression (11.4.3 [class.mfct.non-static] paragraph 3) does not have any special treatment of templates; when C<int>::foo() is instantiated, the reference to A::foo_ turns out to be to a base class member and is thus transformed into (*this).A::foo_ and is thus not an error.

Date User Action Args
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2007-05-06 00:00:00adminsetstatus: dr -> wp
2006-11-05 00:00:00adminsetmessages: + msg1446
2006-11-05 00:00:00adminsetstatus: ready -> dr
2006-04-22 00:00:00adminsetstatus: review -> ready
2005-10-22 00:00:00adminsetmessages: + msg1251
2005-10-22 00:00:00adminsetstatus: open -> review
2005-04-18 00:00:00admincreate