This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[Voted into the WP at the March, 2011 meeting as part of paper N3282.]
Consider the following example:
struct vector { struct iterator { }; struct const_iterator { }; iterator begin(); const_iterator begin() const; }; class block { vector v; auto end() const -> decltype(v.begin()) { return v.begin(); } };
Because the transformation of a member name into a class member access expression (11.4.3 [class.mfct.non.static] paragraph 3) only occurs inside the body of a non-static member function, the type of v in the trailing-return-type is non-const but is const in the return expression, resulting in a type mismatch between the return expression and the return type of the function.
One possibility would be to include the trailing-return-type as being subject to the transformation in 11.4.3 [class.mfct.non.static]. Note, however, that this is currently not in scope at that point (see issue 945).
Notes from the November, 2010 meeting:
The CWG felt that, because this is effectively an implicit parameter, the best approach would be to model its usability on the visibility of parameters: it could be named wherever a parameter of the function is in scope.
Proposed resolution (February, 2011):
Change _N4567_.5.1.1 [expr.prim.general] paragraph 2 as follows, adding three new paragraphs:
The keyword this names a pointer to the object for which a non-static member function (_N4868_.11.4.3.2 [class.this]) is invoked or a non-static data member's initializer (11.4 [class.mem]) is evaluated.
The keyword this shall be used only inside the body of a non-static member function (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 a prvalue.If a function-definition or member-declarator declares a member function of a class X, the expression this is a prvalue of type “pointer to cv-qualifier-seq X” between the optional cv-qualifier-seq and the end of the function-definition or member-declarator. It shall not appear before the optional cv-qualifier-seq and it shall not appear within the declaration of a static member function (although its type and value category is defined within a static member function as it is within a non-static member function). [Note: the type and value category is defined even for the case of a static member function because declaration matching does not occur until the complete declarator is known, and this may be used in the trailing-return-type of the declarator. —end note]
Otherwise, if a member-declarator declares a non-static data member (11.4 [class.mem]) of a class X, the expression this is a prvalue of type “pointer to X” within the optional brace-or-equal-initializer. It shall not appear elsewhere in the member-declarator.
The expression this shall not appear in any other context.
[Example:...
Change _N4567_.5.1.1 [expr.prim.general] paragraph 10 as follows:
An id-expression that denotes a non-static data member or non-static member function of a class can only be used:
...
in the body ofbeyond the optional cv-qualifier-seq in the member-declarator or function-definition that declares a non-static member function of that class or of a class derived from that class (11.4.3 [class.mfct.non.static]), or...
Change 11.4.3 [class.mfct.non.static] paragraph 3 as follows:
When an id-expression (7.5 [expr.prim]) that is not part of a class member access syntax (7.6.1.5 [expr.ref]) and not used to form a pointer to member (7.6.2.2 [expr.unary.op]) is used in thebodydeclaration of anon-staticmember function of class X, if name lookup (6.5 [basic.lookup]) resolves the name...