2009-07-17 72 views
2

我在使用find()函数时出错。下面是代码:find()问题

#include <iostream> 
#include <map> 

#define N 100000 

using namespace std; 

int main (int argc, char * const argv[]) { 

    map<int,int> m; 

    for (int i=0; i<N; i++) m[i]=i; 

    find(m.begin(), m.end(), 5); 

    return 0; 
} 

我发现了一个compiller错误:

error: no match for 'operator==' in '__first. __gnu_debug::_Safe_iterator<_Iterator, _Sequence>::operator* [with _Iterator = std::_Rb_tree_iterator<std::pair<const int, int> >, _Sequence = __gnu_debug_def::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >]() == __val' 

包括 '算法' 没什么变化。在VS2008中编译显示类似的错误。

我知道m.find(),但我真的也需要使用find()了。

非常感谢您的协助!

P.S.实际上,任务是比较m.find(5)和find(m.begin(),m.end(),5)的速度,所以我需要使它们都正常工作。

+0

与比较简单的容器比较,这不是一个更好的测试吗? – 2009-07-17 22:04:11

+0

你能说_why_你需要std :: find而不是成员函数吗?成员函数要快得多。 – rlbond 2009-07-17 22:32:02

回答

8

begin()end()提供这些集合元素的访问权限。这些元素的类型被称为容器的value_type。对于std::map<Key, Value>,其value_typestd::pair<Key, Value>。因此,您的find函数试图找到等于5的pair<int, int>。由于没有定义operator==来比较pair<int, int>int,所以会出现错误。

做到这一点(只要你想避免成员find())正确的方法是使用std::find_if

template <class First> 
struct first_equal 
{ 
    const First value; 

    first_equal(const First& value) 
     : value(value) 
    { 
    } 

    template <class Second> 
    bool operator() (const std::pair<First, Second>& pair) const 
    { 
     return pair.first == value; 
    } 
}; 

... 

find_if(m.begin(), m.end(), first_equal<int>(5)); 

你也可以重载operator==pairint做你想做的,但它的一个非常冒险的方式(因为它会影响你所有的代码,并且因为这样的比较通常没有意义)。

3

find()需要一个可以与* iterator比较的参数。对于你的地图,这将是对< int,int>。您需要创建一个虚拟对,再加上一个比较函数来比较这些对。

+0

只要它的元素是`std :: pair`就可以比较。 – 2009-07-17 21:54:14

+0

这很好理解。你通常不知道你正在搜索的一半,所以它通常不是很有用,但在这种情况下,它可能没有自定义比较函子。 – 2009-07-17 22:01:04

2

只需使用m.find(5)对所有的STL容器