Проблемы со сборкой функции find_if - PullRequest
1 голос
/ 27 мая 2009

Я пытаюсь встроить следующий блок кода в 1-файл .cpp файл:

#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;
}

Я получаю сообщение об ошибке, как показано ниже, и я не совсем уверен, что происходит, когда я использую функцию find_if в методе члена класса, и я получаю эту ошибку всякий раз, когда я делаю это.

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

Ответы [ 4 ]

1 голос
/ 27 мая 2009
int *p = find_if(a, a+10, bind1st(mem_fun(&test::equals), this));

Или, что еще лучше, избавьтесь от этой test::equals() функции-члена, а затем

int *p = find_if(a, a+10, bind2nd(equals(), 9));

где равно равно фактически std::equals(), двоичный функтор, определенный в заголовке <functional>.

1 голос
/ 27 мая 2009

Функция find_if ожидает объект, который можно вызвать как функцию без параметров. Это что-то вроде свободной функции, функционального объекта или статической функции класса. Вы передали адрес функции-члена equals, которая не является ни одной из этих. Вы можете решить эту проблему, сделав функцию equals свободной или статической функцией, поскольку для нее не требуются члены экземпляра 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);

Если ваш пример реального кода требует, чтобы он был функцией-членом, то вам нужно передать объект функции, который действует как замыкание над экземпляром класса. Я предпочитаю использовать метод Boost bind для этого, но есть и другие методы.

int* p = std::find_if(a, a+10, boost::bind(&test::equals, this, _1));
1 голос
/ 27 мая 2009

test::equals - функция-член, синтаксис указателя которой отличается от обычного указателя функции. В частности, чтобы вызвать его, find_if потребуется объект типа test, которого у него нет (например, он не будет автоматически вызывать его на this, что, как я догадываюсь, ты имеешь в виду).

Вы можете переместить функцию equals за пределы класса test, и она должна работать.

0 голосов
/ 27 мая 2009

Третий аргумент find_if должен быть (указатель на) функцию или функтор, принимающий один аргумент, а не (указатель на) метод экземпляра, который вы используете. Например, подходящий функтор может быть (свободно адаптирован из [этой темы] [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;
};

, который позволяет вам делать звонки, как:

std::find_if(a, a+10, is_good_test<test*, int>(10))


  [1]: http://www.velocityreviews.com/forums/t288980-functors-and-stl-findif.html
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...