Rule A5-1-4 (required, implementation, automated)

A lambda expression object shall not outlive any of its referencecaptured objects.

Rationale

When an object is captured by reference in a lambda, lifetime of the object is not tied to the lifetime of the lambda. If a lambda object leaves the scope of one of its reference-captured object, the execution of the lambda expression results in an undefined behavior once the reference-captured object is accessed.

Example

// $Id: A5-1-4.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>

#include <functional>
std::function<std::int32_t()> F()
{
std::int32_t i = 12;
return ([&i]() -> std::int32_t {
i = 100;
return i;
}); // Non-compliant
}
std::function<std::int32_t()> G()
{
std::int32_t i = 12;
return ([i]() mutable -> std::int32_t { return ++i; }); // Compliant
}
void Fn()
{
auto lambda1 = F();
std::int32_t i = lambda1(); // Undefined behavior
auto lambda2 = G();
i = lambda2(); // lambda2() returns 13
}

See also

SEI CERT C++ [10]: EXP61-CPP. A lambda object must not outlive any of its reference captured objects. C++ Core Guidelines [11]: F.53: Avoid capturing by reference in lambdas that will be used nonlocally, including returned, stored on the heap, or passed to another thread.