Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the this pointer inside decltype

Example (compiles fine)

struct A
{
    void f() {};
    auto g() -> decltype(f())
    {}

};

Question

If I add the this pointer inside decltype (i.e. decltype(this->f())), I get the following compile errors with gcc 4.7.0:

error: invalid use of incomplete type 'struct A'
error: forward declaration of 'struct A'
error: invalid use of incomplete type 'struct A'
error: forward declaration of 'struct A'

Is using this in decltype not allowed? Could someone help me understand what is the problem?

EDIT

This has been filed as a bug.

like image 611
Jesse Good Avatar asked Jun 18 '12 23:06

Jesse Good


2 Answers

It seems the problem isn't that this appears inside a decltype, but that it appears outside the function body.

For example, this code below compiles under GCC 4.7:

struct A
{
  int f() { return 0; }
  auto g() -> decltype(f()) {
    decltype(this->f()) var = this->f();
    return var;
  }
};

This uses decltype(this->f()) inside the body of g, but the specification of the return type of the function in the auto .... -> .... form, i.e. the so-called trailing return type specification, is not part of the function body, and GCC does not allow it there.

However, it would appear (see discussion in comments) that the C++ Standard does not actually require this to be used in the function body: §5.1.1 of the standard states that this may be used anywhere between the optional const/volatile qualifier and the end of the function body, see clause 3 below. (For the sake of completeness, I have added clause 4 as well, which talks about data members and is not directly relevant to the question).

(Clause 3) If a declaration declares a member function or member function template of a class X, the expression this is a prvalue of type “pointer to cv-qualifier-seq X” between the optional cv-qualifer-seq and the end of the function-definition, member-declarator, or 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 are defined within a static member function as they are within a non-static member function). [...]

(Clause 4) Otherwise, if a member-declarator declares a non-static data member (9.2) 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.

(Clause 5) The expression this shall not appear in any other context. [...]

NB: The optional cv-qualifier-seq, i.e. the const or volatile qualifier for the function must, as Jesse points out in the comment, appear before the trailing return type declaration. Hence using this in the way described in the question should be correct, and GCC seems to be wrong.

like image 111
jogojapan Avatar answered Oct 02 '22 16:10

jogojapan


The error message seems pretty clear: 'this' is an instance of 'struct A' which is an incomplete type (that is the compiler hasn't finished parsing the structure during the current pass).

like image 26
Nik Bougalis Avatar answered Oct 02 '22 15:10

Nik Bougalis