2009-07-17 70 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容器