The following program do not compile :
#include <iostream> #include <vector> #include <functional> #include <algorithm> #include <cstdlib> #include <cmath> void asort(std::vector<double>& v, std::function<bool(double, double)> f) { std::sort(v.begin(), v.end(), [](double a, double b){return f(std::abs(a), std::abs(b));}); } int main() { std::vector<double> v({1.2, -1.3, 4.5, 2.3, -10.2, -3.4}); for (unsigned int i = 0; i < v.size(); ++i) { std::cout<<v[i]<<" "; } std::cout<<std::endl; asort(v, [](double a, double b){return a < b;}); for (unsigned int i = 0; i < v.size(); ++i) { std::cout<<v[i]<<" "; } std::cout<<std::endl; return 0; }
because :
error : 'f' is not captured
What does it mean and how to solve the problem ?
Captures default to const value. By default, variables are captured by const value . This means when the lambda is created, the lambda captures a constant copy of the outer scope variable, which means that the lambda is not allowed to modify them.
Capture clause A lambda can introduce new variables in its body (in C++14), and it can also access, or capture, variables from the surrounding scope. A lambda begins with the capture clause. It specifies which variables are captured, and whether the capture is by value or by reference.
Permalink. All the alternatives to passing a lambda by value actually capture a lambda's address, be it by const l-value reference, by non-const l-value reference, by universal reference, or by pointer.
Lambdas always capture objects, and they can do so by value or by reference.
You use the f
parameter in the lambda inside asort()
, but you don't capture it. Try adding f
to the capture list (change []
to read [&f]
).
You are effectively referencing f, which is a variable in the outer scope, in your lambda. You should capture it in your capture list (simplest is probably by reference [&f], or [&] to capture everything by reference, as you are using it immediately).
On another note, std::function has some overhead as it performs type erasure, in your case here it might be better to introduce a template type.
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