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.
Imagine that
*this
is a handle class, which maintains ashared_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, anhttp_protocol_socket
).[=, tmp = *this]
will promiscuously capture any variables by value, including, rather dangerously, thethis
pointer itself, as well as specifically capturing*this
intotmp
.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
.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, itsthis
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 withtmp.
. 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 thethis
pointer).