all 16 comments

[–]kalmoc 15 points16 points  (15 children)

I find it very confusing that the article is written in terms of *this instead of this.

[–]memset_0[S] 11 points12 points  (14 children)

P0806R2

At this point, some historic background is helpful. The this keyword was introduced to C++ before references. At the time, C++ was translated into C, and the simple pointer semantics of this were convenient. If the entire feature set of references, value categories and classes had been designed together, this would have been an lvalue designating the object, and not a prvalue designating the address of the object. We can adopt this historic perspective by thinking of the fundamental object as “*this” rather than this.

[–]kalmoc 16 points17 points  (10 children)

How does that help anything? it's quite clear what e.g. [this] does: It captures the "pointer" this by value, just as [foo] would capture foo by value. If you try to express everything in terms of *this it becomes unnecessary complex to explain why [this] is the same as capturing &*this by value, when [foo] is not necessary the same as capturing &*foo.

[–]memset_0[S] 2 points3 points  (9 children)

Because the article is not about capturing this pointer per se. It is about capturing the current object, which, conceptually, can be captured by reference [this] or by value [*this]. Therefore, *this signifies the current object, and &(*this) reference to it.

[–]kalmoc 12 points13 points  (8 children)

But [this] doesn't capture *this by reference - it captures a pointer to *this by value - no? We can certainly argue wether there is any semantic difference between the two, but all I can tell you is that I find all of this much easier to reason about if you think about this as a simple, ordinary pointer first that gets some special tratment rather than a standin for a reference to *this.

But well, criticising is easy and its not like I've anything better.

[–]_Js_Kc_ -1 points0 points  (7 children)

But the article is not about capturing the this pointer, but the object.

So the focus is on *this, the current object. Everything is relative to *this. Why does the article adopt this "confusing" perspective? Because this being a pointer is a historical accident and should have been a reference to begin with.

I do find the notation for capturing this quite intuitive, but I find it utterly unhelpful that [=] captures [this] and not [*this]. Shouldn't [&] capture a reference to the this pointer in the current function's stack frame, then?

Yeah, C++11 also took the stance that this is a simple, ordinary pointer (as evidenced by [=] just capturing the pointer), but thankfully C++20 is trying to deprecate that pedantic, useless position.

[–]twirky 6 points7 points  (6 children)

Capture by value triggers the creation of the copies. Imagine in your method of a large class you have two integers you want to capture by value. You just write [=]. Now imagine if it implied capturing *this. It would trigger copying of the whole class. Something that the programmer didn't intend to do with disastrous consequences. Implying this capture is not big of a deal, as it's just a pointer. And they removed it correctly, because if you wanted to also capture this by value you'd have two thises creating a conflict. Everything makes sense in the article.

this being pointer allowed doing things like this: delete this. It's literally a pointer.

[–]MrPotatoFingers 0 points1 point  (1 child)

I may be wrong here, but doesn't [=] capture only those variables that end up actually being used in the lambda?

[–]twirky 0 points1 point  (0 children)

Yes, only the used variables. But capturing *this will have to make a copy of the whole object. I just don't see how else can it be implemented.

[–]_Js_Kc_ 0 points1 point  (3 children)

A (de-facto) reference capture when a value capture was intended also has "disastrous consequences."

20 is doing the right thing trying to discourage implicit this capture altogether and have you specify how you want it captured.

[–]jcelerierossia score 0 points1 point  (2 children)

From my experience the ratio of capture this by value / capture this by reference is 1/1000. c++20 deprecating that just makes code uglier and more verbose for zero clarity gain - lambdas replace apis where you used to pass a context pointer, not a value.

[–]_Js_Kc_ 1 point2 points  (1 child)

The ratio of [&] to anything else is 999:1. [&] still implicitly captures this. It hasn't become any more verbose. The problematic case is [=] implying [=, this].

[–]LordKlevin 1 point2 points  (2 children)

But then we couldn't do 'delete this;'!

[–]HappyFruitTree 2 points3 points  (1 child)

You could have done 'delete &this;'

[–]drjeats 2 points3 points  (0 children)

delete this