69 lines
1.8 KiB
Plaintext
69 lines
1.8 KiB
Plaintext
== Why is this an issue?
|
||
|
||
When you are using lambdas in a member function, you can capture ``++this++`` implicitly through ``++[=]++`` or ``++[&]++`` or explicitly through ``++[this]++``. It will capture the current object pointer by reference or value, but the underlying object will always be captured by reference (see S5019).
|
||
|
||
|
||
This will become a problem:
|
||
|
||
* When the lifetime of the lambda exceeds the one of the current object.
|
||
* When you want to capture the current state of the object.
|
||
* When you want to pass a copy of the object to avoid any concurrency issue.
|
||
|
||
{cpp}14 provides a solution to this problem. You can copy the underlying object by using the following pattern:
|
||
|
||
[source,cpp]
|
||
----
|
||
auto lam = [copyOfThis = *this] { std::cout << copyOfThis.field; };
|
||
----
|
||
|
||
This is verbose and error-prone, as you might implicitly not use the copied object:
|
||
|
||
[source,cpp]
|
||
----
|
||
auto lam = [& , copyOfThis = *this] {
|
||
std::cout << field; // implicitly calling “this” captured by reference
|
||
};
|
||
----
|
||
|
||
{cpp}17 solves this problem by introducing an explicit, consistent way to capture ``++this++`` by copy:
|
||
|
||
[source,cpp]
|
||
----
|
||
auto lam = [&, *this] {
|
||
std::cout << field // implicitly calling “this” captured by copy
|
||
};
|
||
----
|
||
|
||
This rule will flag the {cpp}14 way of capturing the current object by copy and suggest replacing it with the {cpp}17 way.
|
||
|
||
|
||
=== Noncompliant code example
|
||
|
||
[source,cpp,diff-id=1,diff-type=noncompliant]
|
||
----
|
||
struct A {
|
||
int field = 0;
|
||
void memfn() const {
|
||
auto lam = [copyOfThis = *this] { // Noncompliant
|
||
std::cout << copyOfThis.field;
|
||
};
|
||
}
|
||
};
|
||
----
|
||
|
||
|
||
=== Compliant solution
|
||
|
||
[source,cpp,diff-id=1,diff-type=compliant]
|
||
----
|
||
struct A {
|
||
int field = 0;
|
||
void memfn() const {
|
||
auto lam = [*this] { // Compliant
|
||
std::cout << field;
|
||
};
|
||
}
|
||
};
|
||
----
|
||
|