2010-07-29 2 views
0

Я пытаюсь использовать STL, но следующее не компилируется. main.cpp:C++: ошибка C2064 с STL

#include <set> 
#include <algorithm> 

using namespace std; 

class Odp 
{ 
public: 

    set<int> nums; 

    bool IsOdd(int i) 
    { 
     return i % 2 != 0; 
    } 

    bool fAnyOddNums() 
    { 
     set<int>::iterator iter = find_if(nums.begin(), nums.end(), &Odp::IsOdd); 
     return iter != nums.end(); 
    } 
}; 

int main() 
{ 
    Odp o; 
    o.nums.insert(0); 
    o.nums.insert(1); 
    o.nums.insert(2); 
} 

Ошибка:

error C2064: term does not evaluate to a function taking 1 arguments 
1>   c:\program files\microsoft visual studio 10.0\vc\include\algorithm(95) : see reference to function template instantiation '_InIt std::_Find_if<std::_Tree_unchecked_const_iterator<_Mytree>,_Pr>(_InIt,_InIt,_Pr)' being compiled 
1>   with 
1>   [ 
1>    _InIt=std::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>>, 
1>    _Mytree=std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>, 
1>    _Pr=bool (__thiscall Odp::*)(int) 
1>   ] 
1>   main.cpp(20) : see reference to function template instantiation '_InIt std::find_if<std::_Tree_const_iterator<_Mytree>,bool(__thiscall Odp::*)(int)>(_InIt,_InIt,_Pr)' being compiled 
1>   with 
1>   [ 
1>    _InIt=std::_Tree_const_iterator<std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>>, 
1>    _Mytree=std::_Tree_val<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>, 
1>    _Pr=bool (__thiscall Odp::*)(int) 
1>   ] 

Что я делаю неправильно?

ответ

3

Он должен быть объявлен статическим:

static bool IsOdd(int i) 

В противном случае, вы бы просить find_if вызвать метод экземпляра без экземпляра.

1

Проблема: вы передаете указатель на функцию-член. Для вызова этой функции вам также понадобится указатель на это, но find_if не позволит вам передать его. Решение состоит в том, чтобы обернуть его с помощью функционального объекта, см. «Ускорение привязки» (http://www.boost.org/doc/libs/1_43_0/libs/bind/bind.html) и функции усиления (http://www.boost.org/doc/libs/1_37_0/doc/html/function.html).

1

IsOdd не использует внутренние элементы класса в любом случае, поэтому не делайте его функцией-членом. Вместо этого вытащите его как отдельную функцию. Затем вы можете позвонить find_if с &IsOdd.

Однако, есть выгода для принятия вещи шага дальше и определив его как функциональный объект:

#include <functional> 

struct IsOdd : public unary_function<int, bool> 
{ 
    bool operator()(int i) const { return i % 2 != 0; } 
}; 

Тогда вызывающего find_if с IsOdd() будет рядного код внутри цикла find_if вместо разыменования указатель функции и вызов функции.

Смежные вопросы