this in unevaluated context in static member functions

288 views Asked by At

Why this is not allowed in unevaluated context in static member functions?

struct A
{
    void f() {}
    static void callback(void * self) // passed to C function
    {
        static_cast< decltype(this) >(self)->f();
    }
};

This code gives an error:

error: 'this' is unavailable for static member functions

static_cast< decltype(this) >(self)->f();
                      ^~~~

decltype(this) there is needed for brevity (sometimes it is much more shorter, then VeryVeryLongClassName *), another advantage is the fact that intention is more clear.

What Standard says about using this in unevaluated contexts in static member functions?

2

There are 2 answers

1
Praetorian On BEST ANSWER

I don't see how it matters that this appears within an unevaluated context, you've referred to something that doesn't exist in a static member function, so how is the compiler supposed to deduce the type of this within this context?

As a corollary, the type of this in a non-static member function is dependent on the cv-qualifier of said member function, decltype(this) would yield T const* if the member function were const, and T * if it weren't. Thus, the type is dependent on the context of the expression. In your example, the context has no this pointer.

To alleviate the pain of having to name the class you could add an alias for it.

class VeryVeryLongClassName
{
    using self = VeryVeryLongClassName;
};
0
Ben Voigt On

The current draft of the Standard has some conflicting information.

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" wherever X is the current class between the optional cv-qualifier-seq and the end of the function-definition, member-declarator, or declarator. It shall not appear within the declaration of either a static member function or an explicit object member function of the current class (although its type and value category are defined within such member functions as they are within an implicit object member function).

First it prohibits the expression this in a static member function, but then it says that the type and value category of this are defined within static member functions (and it does so in a way which resolves the question of cv qualification). Which seems useless if there is no way to refer to said this to obtain its type.

A potential resolution would be for the rule to change from "shall not appear" to "shall not be evaluated", which would immediately permit it to appear in unevaluated context such as decltype and sizeof.