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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With