Find_if function construction problems
I am trying to build the following block of code in a .cpp file with 1 file:
#include <iostream>
#include <algorithm>
using namespace std;
class test
{
public:
int a[10];
int index;
test();
~test();
bool equals(int p);
void search();
};
test::test()
{
int temp[10] = {4, 9, 5, 6, 9, 10, 9, 255, 60, 0};
memcpy(a, temp, sizeof(temp));
index = -1;
}
bool test::equals(int p)
{
return p == 9;
}
void test::search()
{
int* p = std::find_if(a, a+10, &test::equals);
while (p != a+10)
{
cout<< *p;
index = p - a;
p = std::find_if(p+1, a+10, &test::equals);
}
}
int main(int argc, char *argv[])
{
test object;
object.search();
return 0;
}
I am getting an error like below and I am not sure exactly what happens when I use the find_if function in a member method of a class and I get this error whenever I do this.
1> c: \ program files \ microsoft visual studio 8 \ vc \ include \ algorithm (87): error C2064: term does not evaluate to a function taking 1 arguments 1> c: \ program files \ microsoft visual studio 8 \ vc \ include \ algorithm (96): see reference to function template instantiation '_InIt std :: _ Find_if (_InIt, _InIt, _Pr)' being compiled 1> with 1> [ 1> _InIt = int *, 1> _Pr = bool (__thiscall test :: *) (int) 1>] 1> c: \ testprogram \ nomfc \ main.cpp (32): see reference to function template instantiation '_InIt std :: find_if (_InIt, _InIt, _Pr)' being compiled 1> with 1> [ 1> _InIt = int *, 1> _Pr = bool (__thiscall test :: *) (int) 1>]
a source to share
The function find_if
expects an object that can be called as a function with no parameters. It is something like a free function, a function object, or a static function of a class. You passed the address to a function equals
that is not one of them. You can solve this problem by making the function a equals
free function or a static function, since it does not require any instance members test
.
// static
class test
{
public:
static bool equals(int p); // etc
};
int* p = std::find_if(a, a+10, &test::equals);
// free
bool equals(int p)
{
return p == 9;
}
int* p = std::find_if(a, a+10, equals);
If your real code example requires it to be a member function, you need to pass a function object that acts as a closure over the class instance. I prefer to use the Boost binding method for this, but there are other methods as well.
int* p = std::find_if(a, a+10, boost::bind(&test::equals, this, _1));
a source to share
test::equals
is a member function that has a different pointer syntax from a normal function pointer. In particular, calling it find_if
requires an object of a type test
that it doesn't have (for example, it won't automatically call it on this
, which I assume is what you mean).
You can move the function equals
outside of the class test
and it should work.
a source to share
int *p = find_if(a, a+10, bind1st(mem_fun(&test::equals), this));
Or better yet, get rid of that member function test::equals()
and then
int *p = find_if(a, a+10, bind2nd(equals(), 9));
where equals is actually a std::equals()
binary functor, as defined in the header <functional>
.
a source to share
The third argument find_if
must be a (pointer to a) function or functor taking one argument, not (pointer to) the instance method you are using. For example, a suitable functor might be (loosely adapted from [this thread] [1]):
template <typename PType, typename ArgType>
class is_good_test : unary_function<PType, bool>
{ public:
is_good_test(const ArgType & arg) : _val(arg) { }
~is_good_test() { }
bool operator()(const PType p) const
{
return p->equals(_val);
}
private:
ArgType _val;
};
which allows calls like:
std::find_if(a, a+10, is_good_test<test*, int>(10))
[1]: http://www.velocityreviews.com/forums/t288980-functors-and-stl-findif.html
a source to share