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>]
+1


a source to share


4 answers


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));

      

+1


a source


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.

+1


a source


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>

.

+1


a source


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

      

0


a source







All Articles