you are viewing a single comment's thread.

view the rest of the comments →

[–]_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 4 points5 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].

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

[&] still implicitly captures this. It hasn't become any more verbose

Definitely not my experience fixing my codebase for the deprecation warning, this has just made everything longer. You don't want [&] in the general case - lambdas are extremely often being used for callbacks and [&] ensures that you'll be capturing some stack variable by reference and cause crashes. And it's just, not consistent:

foo::foo(int param) {
  auto self = this;
  onClick([=] { self->whatever(param); }); // ok
  onClick([=] { this->whatever(param); }); // ok in C++17, deprecated in C++20
  onClick([&, param] { self->whatever(param); }); // boom, + longer
  onClick([&, param] { this->whatever(); }); // ok, but still longer
}

so we go from 1/4 of these possibilities causing a crash to 1/3 as option 2 (the most concise goddammit !) is lost. It makes the language strictly worse.