Inside of a class, why `auto b() -> decltype(a()) {}` works, but `decltype(a()) b() {}` does not?

后端 未结 2 919
傲寒
傲寒 2021-01-07 20:37

Consider following code: (Ideone)

struct S
{
    int a() {return 0;}
    decltype(a()) b() {return 1;}
};

It gives me following error:

2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-07 20:41

    A few additions to @Brian's answer:

    1. In the first example, the a() is not transformed to (*this).a(). That transformation is specified in [class.mfct.non-static]/3 and only takes place "in a context where this can be used". Without this transformation, the code is then ill-formed for violating [expr.prim.id]/2:

      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 ([expr.ref]) in which the object expression refers to the member's class63 or a class derived from that class, or

      • to form a pointer to member ([expr.unary.op]), or

      • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

      by using the id-expression a, which denotes a non-static member function, outside the allowed contexts.

    2. The fact that the transformation to class-member access doesn't take place is important because it makes the following code valid:

      struct A {
          int a;
          decltype(a) b();
      };
      

      If decltype(a) above were transformed into decltype((*this).a), then the code would be ill-formed.

    3. *this has a special exemption from the usual rule that the object in a class member access must have complete type ([expr.prim.this]/2):

      Unlike the object expression in other contexts, *this is not required to be of complete type for purposes of class member access ([expr.ref]) outside the member function body.

提交回复
热议问题