Reputation: 12541
I have no idea what to title this question as, sorry.
I have a function in C++ which takes a lambda as a parameter.
void LoopPixels(cv::Mat &img, void(*fptr)(uchar &r, uchar &g, uchar &b)) {
// ...
fptr(r, g, b); // Call the lambda function
}
Then I am trying to call this LoopPixels
function.
int threshold = 50;
LoopPixels(img, [](uchar &r, uchar &g, uchar &b) {
r *= (uchar)threshold; // Unable to access threshold :(
});
My problem is, I cannot access the threshold
variable from inside the lambda function, and if I try to "catch" it with [&threshold](uchar &r...){}
, I receive an error telling me the lambda I parsed into LoopPixels
is of the wrong type.
Error message:
no suitable conversion function from "lambda []void (uchar &r, uchar &g, uchar &b)->void" to "void (*)(uchar &r, uchar &g, uchar &b)" exists
How can I access variables within a lambda which has been parsed as a function argument?
Upvotes: 2
Views: 416
Reputation: 11
You can try to use this:
void LoopPixels(cv::Mat& img, uint& r, uint& g, uint& b, const std::function<void(uint& r, uint& g, uint& b)>& callback)
{
callback(r, g, b);
}
cv::Mat img;
int threshold = 50;
uint r = 1;
uint g = 1;
uint b = 1;
std::cout << "(before) rgb : " << r << g << b << std::endl;
LoopPixels(img, r, g, b, [threshold](uint& r, uint& g, uint& b)
{
r *= threshold;
g *= threshold;
b *= threshold;
});
std::cout << "(after) rgb : " << r << g << b << std::endl;
The lamba capture is passed by value because the reference could go out of scope before the callback call.
(I used uint for r, g, b variables instead of uchar because multiplying a uchar for an int might not give the result you expect).
Upvotes: 0
Reputation: 18915
You cannot pass a capturing lambda to a function pointer. You have to change the function to use a std::function
, or use a function template.
void LoopPixels1(cv::Mat &img, std::function<void(uchar &r, uchar &g, uchar &b)> fn);
// Or:
template<typename Callable>
void LoopPixels2(cv::Mat &img, Callable fn);
// Can be called with a capturing lambda
LoopPixels1(img, [threshold](uchar &r, uchar &g, uchar &b) { });
LoopPixels2(img, [threshold](uchar &r, uchar &g, uchar &b) { });
Upvotes: 5