'Initialise a lambda function to be passed as a predicate to std::find_if in C++
I'm trying to initialise a lambda function and then passing as a predicate to std::find_if but receiving the following compiler error. "expression cannot be used as a function".
So how do you first initialise a lambda as a type auto variable and pass it in as a predicate function to an algorithm like std::find_if?
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<std::string> vec ={"this", "is", "a", "test", "to",
"see","if", "this", "works", "to", "this", "if"};
auto elimDups_lambda
{
[&vec]()
{
std::sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
return vec;
}
};
for(auto& iter_vec:elimDups_lambda())
std::cout<<iter_vec<<std::endl;
auto lambda_size
{
[&vec](size_t x)
{
for(auto& iter_vec:vec)
{
if(iter_vec.size()==x)
return true;
else if(iter_vec >*vec.end())
return false;
}
}
};
size_t string_size =0;
std::cin>>string_size;
std::vector<std::string>::iterator find_word =
std::find_if(vec.begin(), vec.end(), lambda_size(string_size));
std::cout<<*find_word<<std::endl;
return 0;
}
Thank you.
Solution 1:[1]
In order to define a variable holding a lambda, you can use syntax similar to this:
auto lambda_var =
[&vec]()
{
std::sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
return vec;
};
To use it when calling std::find_if, pass lambda_var (or the name of the variable holding the lambda that you need), as a 3rd parameter to std::find_if
in your code elimDups_lambda and lambda_size are not properly defined to be variables holding lambdas (if this is indeed what you wanted to achieve).
Solution 2:[2]
With the expression
lambda_size(string_size)
you call the lambda function, and then the returned bool result will be used as the predicate for std::find_if.
This will of course not work very well.
You can solve this in two ways:
Capture
string_sizein the lambda; OrMake the lambda return another lambda for the size check:
auto lambda_size = [&vec](size_t size) { return [size](std::string const& word) { return word.length() == size; } }
Also note how I have changed the logic in the lambda for the comparisons. Your comparison could mean that you dereference the end() iterator for the vector, which isn't allowed. And also that there's a path where the lambda doesn't actually return anything.
Both those problems inside the lambda would lead to undefined behavior.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | wohlstad |
| Solution 2 |
