32

C++17 will add copy capture of this object by value, with a capture specification of [*this].

How is this useful? How is it different than capturing this? Can't this already be achieved in C++14 with [tmp = *this]?


Bonus for explaining why P0018R3 uses [=, tmp = *this] instead of [tmp = *this] in their example. If they had used [tmp = *this], all the listed downsides of the C++14 solution would be eliminated.

2
  • 4
    I guess they simplified the examples too much. Once you add additional local variables or parameters, you'd want to capture them by copy. Then the [=, ..] part makes sense (if you don't want to capture them explicitly one-by-one, that is). Commented Jan 13, 2017 at 15:14
  • It might be helpful to draw on analogies between non static member functions and other functions, even between C++ and what C++ could have been if, during the history of "C with classes", references came before member functions (this is only pointer because there were no references when it was invented). Commented Jan 26, 2019 at 3:15

2 Answers 2

35

How is it useful? It's useful when you need a copy of *this - for example, when *this itself is no longer valid by the time the lambda is evaluated.

How is it different from capturing this? It makes a copy of the object, so that when the lambda is evaluated, its this pointer refers to the copy, rather than to the original object.

Can it be achieved in C++14 with [tmp = *this]? It can, but [*this] is more convenient, as code can be moved without prefixing member access with tmp.. Otherwise, especially with [=, tmp = *this], it's possible to accidentally refer to members of the original object when you meant to refer to the copy (particularly if you're in the habit of cut+paste programming). [=,*this] is a safer alternative in this case, as the original object is not accessible from inside the lambda's body (at least, not via the this pointer).

Sign up to request clarification or add additional context in comments.

4 Comments

this is a scalar rvalue since the first "serious" C++ (only in primitive C++ was it assignable), you can't refer to an object this, only to the value of this.
@curiousguy, I'm not sure what your criticism here is. Have I been ambiguous with terminology somewhere? I see that I've written "the (original) object" when talking about *this - is that giving you problems?
There is no such thing as the original value of a pointer; a pointer value is a pointer value is a pointer value. "the original this" makes no sense.
Thanks @curiousguy, I think I see what you mean now. I'll try and think of a clearer way to phrase what I meant. (Time passes). Better?
6

Imagine that *this is a handle class, which maintains a shared_ptr to some shared state.

The shared impl is (for example) a protocol handler state machine.

The handle class is passed through a series of asynchronous handlers, so itself must be copyable. Each handler mutates the shared state.

A strong use case for this might be a protocol handler for use with a custom asio service (for example, an http_protocol_socket).

[=, tmp = *this] will promiscuously capture any variables by value, including, rather dangerously, the this pointer itself, as well as specifically capturing *this into tmp.

In this use case it would be dangerous to inadvertently refer to this in the async handler, because it's likely to be a dangling pointer. This is a bug waiting to happen.

[tmp=*this] will only capture *this.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.