Wednesday, August 31, 2022

[SOLVED] how to use decltype(*this) in clang

Issue

Here is my code.

If i don't comment out the // typedef auto getFoo1() -> decltype(*this);,the program works on gcc,but it compiles failed on clang (href="https://godbolt.org/z/jzs3f6oM7" rel="nofollow noreferrer">https://godbolt.org/z/jzs3f6oM7).


class Foo {
public:

    // not work on clang but work on gcc
    // typedef auto getFoo1() -> decltype(*this);

    auto getFoo2() -> decltype(*this);

};



int main() {
    Foo f;


    return 0;
}

The error is

<Compilation failed>

# For more information see the output window
x86-64 clang 14.0.0 - 1232ms
Output of x86-64 clang 14.0.0 (Compiler #1)
<source>:6:41: error: invalid use of 'this' outside of a non-static member function
    typedef auto getFoo1() -> decltype(*this);

And I want to know, what is the difference between the getFoo1() and the getFoo2()? And if getFoo1() and getFoo2() exists in memory or other place when running?


Solution

There are only few places where this is allowed to appear and [expr.prim.this] lists them all, namely it can appear in declarations of member functions, member function templates and default initializers of non-static data members.

A typedef declares a type alias, so neither of those above, and therefore this is not allowed to appear in the typedef declaration. GCC is wrong to accept it.

This rule also makes sense. this only really makes sense in a non-static member function definition. Its value and also its type depend on that. For example this ought to be const-qualified if and only if the non-static member function is const-qualified.

However a typedef of the form

typedef auto getFoo1() -> decltype(*this);

has nothing to do with member functions. It simply declares a type alias for an ordinary function type that could be used to declare any function, whether member function or not, and potentially in any class. What type should this even have then in this context? Foo*, const Foo*, etc?

If you need to just refer to the class type itself, use Foo directly instead of going through decltype(*this).



Answered By - user17732522
Answer Checked By - Cary Denson (WPSolving Admin)