On Fri, Apr 7, 2023 at 3:37 PM Jan Schultke via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
No, I don't have a working implementation, but here is an example that
demonstrates the benefits:
https://www.godbolt.org/z/Ejn9KK57x

When the polymorphic class is already de-virtualized, then returning
Base& breaks the de-virtualization in the second and third call. With
a "this" return type, we would have the guarantee that the dynamic
type stays the same, so we can keep making direct calls.

The only exception to this is when a virtual function ends and begins
the lifetime of "this" before returning, though I'm not sure if this
is really allowed by the standard, and could also be declared UB for
this return types, if need be.

IIUC, your example intends that the `this` keyword would be used both in `Base` and also in `B`, is that right?
https://www.godbolt.org/z/xWdcaoxE6
I think Lénárd might have been thinking that the `this` keyword would be used only in `B` but not in `Base`.

There are a lot of semantic question-marks to be filled in here:
(1) In this program, what is decltype(Derived().f()) — is it automatically the covariant type `Derived&`, or is it the same `Base&` as in the parent class?
    struct Base { virtual this f(); };
    struct Derived { this f() override; }  // What is the return type of this method?
(2) Is it allowed for a derived class to use `this` where its parent class doesn't? Again, what is decltype(Derived().f()) in this case?
    struct Base { virtual Base& f(); };
    struct Derived { this f() override; }   // OK, or error?
(3) Is it allowed for a derived class to omit `this` where its parent class has it? I assume not. But one could imagine its working like `virtual`, and being implied if the parent class has it.
    struct Base { virtual this f(); };
    struct Derived { Derived& f() override; }  // OK, or error?
(4) Is it simply UB for such a function to return anything but `*this`? Does the compiler enforce this at all?
    struct S { this f(bool b) { static S s; if (b) return s; } };  // UB-if-taken, or IFNDR, or hard error, or what?

Plus a syntactic question-mark or two:
(5) Is this in trailing position allowed?
    struct S { auto f() -> this; };
(6) Is this part of the function's type? Presumably not.
    using MFP1 = Base& (Base::*)();  // OK
    using MFP2 = this (Base::*)();  // Pretty sure this must be a syntax error; the real-estate is already taken

Finally, if you do pursue an implementation of this (I'm not saying you should look to standardize it — the syntactic space is already insanely crowded, and C++23 makes it worse), it would naturally lend itself to an extension of P2266 implicit move.  See:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1155r1.html#further
(7) The idea is:
    struct X { X& operator=(const X&); };
    struct Y { this operator=(const Y&); };
    X f() { X x; return x = X(); }
    Y g() { Y y; return y = Y(); }
In the former case we must treat `x = X()` as an lvalue expression and copy-construct from `x` into the return slot.
In the latter case, we know that `y = Y()` refers to the same object as `y`, and so we can (a) treat it as an lvalue, and (b) optionally subject it to NRVO/copy-elision.
A proposal should engage with this issue somehow — either propose to do the efficient thing now that it's implementable, or else explain why you're not proposing the efficient thing.

(8) I like(*) the proposed streamlining of
    A& operator=(A a) { swap(*this, a); return *this; }
    A& operator++() { ++member_; return *this; }
into
    this operator=(A a) { swap(*this, a); }
    this operator++() { ++member_; }
but I do vaguely worry that it might lead to a spate of people writing something like
    this operator++(int) { member_++; }
which of course isn't going to work. Probably not a big deal, though, because the "edit distance" between the dumb thing I just wrote and the actually correct `operator++(int)` is pretty far — I don't currently see any really plausible way for someone to get all the way to hitting "Compile" without realizing that what they wrote is silly.

(* — However, if I wanted to streamline the implementation of copy-and-swap `operator=`, I wouldn't pick that point to stop. That's a sour spot: we've made the syntax obscure but we still have to write too many tokens to actually get the job done. Meanwhile the syntax for a defaulted memberwise `operator=` is already optimal: `=default`.)

my $.02,
–Arthur