In the following function, can I rely on the captured variable 'order' to be up to date, i.e.
struct Entry
{
std::string name;
double earnings;
};
enum Column { Name, Earnings };
enum SortOrder { Ascending, Descending };
void sortByColumn(std::vector<Entry>& entries, Column column, SortOrder order)
{
std::function<bool(const Entry&, const Entry&)> comparators[] =
{
[&](const Entry& a, const Entry& b) { return order==Ascending ?
a.name < b.name : a.name > b.name; },
[=](const Entry& a, const Entry& b) { return order==Ascending ?
a.earnings < b.earnings : a.earnings > b.earnings; }
};
std::sort(entries.begin(), entries.end(), comparators[column]);
}
You can find a full example here: http://coliru.stacked-crooked.com/a/240b74d1706a1b6f
The thing that you must recognize is that a lambda is a closure type object:
The lambda expression is a prvalue expression an unnamed temporary object of unique unnamed non-union non-aggregate class type, known as closure type, which is declared (for the purposes of Argument-Dependent Lookup) in the smallest block scope, class scope, or namespace scope that contains the lambda expression[source]
You can think of the lambda's capture list as constructor arguments. In this case you passed order by value/reference into the 1st/2nd comparators respectively. Since order does not change over the lifetime of comparators, passing by reference or value will have identical results in your example.
But if this function were called with order set to Ascending and you added this to the bottom of sortByColumn:
order = Descending;
std::sort(entries.begin(), entries.end(), comparators[0]);
You would have sorted entries by name in descending order. Meaning the change to order effected the lambda.
If you'd done this however, and sortByColumn was again passed order as Ascending:
order = Descending;
std::sort(entries.begin(), entries.end(), comparators[1]);
You would have sorted entries by earnings in ascending order. Meaning the change to order did not effect the lambda.
When deciding whether to capture by reference the same considerations should be applied that you use in deciding whether or not to use a reference or copy as an object member:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With