Reputation: 10934
I'm trying to build the following block of code in a 1-file .cpp 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 as shown below, and I'm not sure exactly what's happening when I use the find_if function in a member method of a class, and I'm getting this error whenever I am doing so.
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> ]
Upvotes: 1
Views: 2377
Reputation: 135265
The find_if
function expects an object which is callable as a function with no parameters. This is something like a free function, a function object or a static class function. You passed in the address of the equals
member function which is none of these. You could resolve this by making the equals
function a free function or a static function, since it does not require any members of the test
instance.
// 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 that it be a member function, then you need to pass in a function object that acts as a closure over the class instance. I favour using the Boost bind method for this, but there are other methods as well.
int* p = std::find_if(a, a+10, boost::bind(&test::equals, this, _1));
Upvotes: 1
Reputation: 58677
int *p = find_if(a, a+10, bind1st(mem_fun(&test::equals), this));
Or better yet, get rid of that test::equals()
member function and then
int *p = find_if(a, a+10, bind2nd(equals(), 9));
where equals is in fact std::equals()
, a binary functor defined in header <functional>
.
Upvotes: 1
Reputation: 881605
The third argument to find_if
must be a (pointer to a) function or functor taking one argument, not a (pointer to an) instance-method which is what you're using. For example, an appropriate 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 lets you do 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
Upvotes: 0
Reputation: 34034
test::equals
is a member function, which has different pointer syntax from an ordinary function pointer. In particular, to call it, find_if
would need an object of type test
, which it doesn't have (it won't, for example, automatically call it on this
, which I'm guessing is what you have in mind).
You can move the function equals
outside the class test
, and it should work.
Upvotes: 1