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

2024-04-05


760. this inside a nested class of a non-static member function

Section: _N4567_.5.1.1  [expr.prim.general]     Status: CD2     Submitter: Mike Miller     Date: 3 February, 2009

[Voted into WP at March, 2010 meeting.]

this is a keyword and thus not subject to ordinary name lookup. That makes the interpretation of examples like the following somewhat unclear:

    struct outer {
      void f() {
        struct inner {
          int a[sizeof(*this)];  // #1
        };
      }
    };

According to _N4567_.5.1.1 [expr.prim.general] paragraph 3,

The keyword this shall be used only inside a non-static class member function body (11.4.2 [class.mfct]) or in a brace-or-equal-initializer for a non-static data member.

Should the use of this at #1 be interepreted as a well-formed reference to outer::f()'s this or as an ill-formed attempt to refer to a this for outer::inner?

One possible interpretation is that the intent is as if this were an ordinary identifier appearing as a parameter in each non-static member function. (This view applies to the initializers of non-static data members as well if they are considered to be rewritten as mem-initializers in the constructor body.) Under this interpretation, the prohibition against using this in other contexts simply falls out of the fact that name lookup would fail to find this anywhere else, so the reference in the example is well-formed. (Implementations vary in their treatment of this example, so clearer wording is needed, whichever way the interpretation goes.)

Proposed resolution (February, 2010):

Change _N4567_.5.1.1 [expr.prim.general] paragraph 2 as follows:

...The keyword this shall be used only inside the body of a non-static class member function body (11.4.2 [class.mfct]) of the nearest enclosing class or in a brace-or-equal-initializer for a non-static data member (11.4 [class.mem]). The type of the expression is a pointer to the class of the function or non-static data member, possibly with cv-qualifiers on the class type. The expression is an rvalue. [Example:

  class Outer {
    int a[sizeof(*this)];            // error: not inside a member function
    unsigned int sz = sizeof(*this); // OK, in brace-or-equal-initializer

    void f() {
      int b[sizeof(*this)];          // OK

      struct Inner {
        int c[sizeof(*this)];        // error: not inside a member function of Inner
      };
    }
  };

end example]