Reputation: 483
I want to count the number of elements greater than a number in a c++ vector. The threshold value is to be taken input from the user.
The code for counting elements greater than a number is given as:
ctr=count_if(v.begin(),v.end(), greater1);
The corresponding function:
bool greater1(int value)
{
return value >= 8;
}
The problem is I would know the threshold value(here 8) only before the count_if
function call so I need to pass the threshold t
as a parameter. How to establish the same?
Upvotes: 2
Views: 5611
Reputation: 180945
N.B. Only for c++11 standard
The easiest way to do this is to use a lambda expression. Using that you can build a functor (called a Closure Object) in the call site of count_if
and you can use what you known then inside the body of the lambda. That would leave you with something like
auto minimum_value = /* something that gets the minimum value you want to use for the comparison */
auto count = std::count_if(v.begin(), v.end(),[&](auto const& val){ return val >= minimum_value; });
// ^ use this to capture a reference of minimum_value
Upvotes: 9
Reputation: 41145
Like NathanOliver said, we need to "capture" the threshold value to be used internally. A lambda accomplishes that, but how?
When you write a lambda like
int threshold = 8;
std::count_if(/*...*/, [threshold](int next_val){return next_val >= threshold;});
In C++11 and beyond, the compiler uses this lambda syntax to generate a lightweight class that exposes the function call operator like so:
struct my_greater_equal
{
explicit my_greater_equal(int _threshold) : threshold(_threshold){}
bool operator()(int next_val) const
{
return next_val >= threshold;
}
int threshold;
};
(This is only mostly like what a lambda looks like)
Then an instance is created and used in count_if
as-if:
std::count_if(my_collection.cbegin(), my_collection.cend(), my_greater_equal{8});
Internally, std::count_if
calls my_greater_equal::operator()
for each element in your collection.
Pre-C++11 we had to manually create these lightweight function objects (sometimes called functors even if that's not technically correct)
Things are much easier now :-)
Upvotes: 2
Reputation: 10740
Make a function that gives you the threshold function!
auto above(int threshold) {
// This captures a copy of threshold
return [=](int value) {
return value >= threshold;
};
};
You can then get the count using above
, just by passing the threshold as an argument:
auto count = count_if(v.begin(), v.end(), above(8));
Upvotes: 3