Reputation: 373
Suppose I have the following code:
#include <vector>
#include <algorithm>
#include <cmath>
bool pred(float const &val)
{
//return fabs(val) < epsilon;
}
class Foo
{
public:
Foo(float eps) : epsilon(eps) { }
int Bar(std::vector<float> vec)
{
return std::count_if(vec.begin(), vec.end(), pred);
}
private:
float epsilon;
}
I want to have the unary predicate pred()
as a class method so that it can access the epsilon
member variable. I've seen examples using the operator()
, but if I got it right, the operator is supposed to compare the entire class instance. I only need to compare the given std::vector
's elements in Bar()
. Is it possible to create an unary predicate as a class member? If not, is there any other way to do it?
Upvotes: 3
Views: 3561
Reputation: 3861
Your problem is that pred() needs two parameters but std::count_if wants a function that takes only one. @Praetorian's c++11 solution with lambdas is optimal. But without access to that, you should be able to use std::bind1st which does the operator () solution for you without you explicitly creating a class to do it.
#include <vector>
#include <algorithm>
#include <cmath>
#include <functional>
bool pred(float const &val, float epsilon)
{
return fabs(val) < epsilon;
}
class Foo
{
public:
Foo(float eps) : epsilon(eps) { }
int Bar(std::vector<float> vec)
{
return std::count_if(vec.begin(), vec.end(), std::bind1st(std::less<float>(), epsilon));
}
private:
float epsilon;
};
Upvotes: 2
Reputation: 5502
Here's a C++98 solution:
class Pred{
private:
float eps;
public:
Pred(float eps) : eps(eps){
}
bool operator()(const float& val){
return val < eps;
}
};
And use it like this:
int Bar(std::vector<float> vec)
{
Pred pred(epsilon);
return std::count_if(vec.begin(), vec.end(), pred);
}
Note that this solution is general for whenever you need a predicate that requires additional data; write a class containing the additional data as class members, and overload the ()
operator. You can initialize an object of the class with the appropriate data and then use it as the predicate.
Upvotes: 2
Reputation: 25505
if you are using c++ 11 which you should be the easy way is a lambda
int Bar(std::vector<float> vec)
{
return std::count_if(vec.begin(), vec.end(),[this](const float &f)
{
return fabs(val) < epsilon;
});
}
Upvotes: 4