Let's say I have two local smart pointers, foo
and bar
.
shared_ptr<Foo> foo = ...
shared_ptr<Bar> bar = ...
These smart pointers are wrappers around resources that for some reason must be destructed in the order foo
, then bar
.
Now I want to create a lambda that uses foo
and bar
, but outlives the scope containing them. So I'd capture them by value, like this:
auto lambda = [foo, bar]() { ... };
This creates copies of foo
and bar
within the function object. When the function object is destructed, these copies will be destructed, as well, but I care about the order in which this happens. So my question is:
When a lambda object is destructed, in what order are its by-value captures destructed? And how can I (hopefully) influence this order?
The spec covers this... sort of. From 5.1.2, paragraph 14:
An entity is captured by copy if it is implicitly captured and the capture-default is = or if it is explicitly captured with a capture that does not include an &. For each entity captured by copy, an unnamed non-static data member is declared in the closure type. The declaration order of these members is unspecified.
Emphasis added. Because the declaration order is unspecified, the construction order is unspecified (since the order of construction is the same as the order of declaration). And therefore, the destruction order is unspecified, since the order of destruction is the reverse of the order of construction.
In short, if you need to care about declaration order (and the various construction/destruction orders that key off of it), you cannot use a lambda. You'll need to make your own type.