2012-10-08 72 views
1

我有一個Visual Studio 2008 C++ 03應用程序,我想創建一個使用來自另一個std::map的迭代器作爲其鍵類型的std::map。但是,當我嘗試使用其鍵類型擦除該地圖中的元素時,我遇到了一個問題。使用一個映射中的迭代器作爲另一個鍵的類型

在這個例子中,當MyList中的元素變得超過5分鐘時,計時器應該觸發並從地圖中移除它並銷燬其年齡計時器。

typedef std::map< Foo, FooBar > MyList; 
typedef std::map< MyList::iterator, boost::shared_ptr<Timer> > MyListAgeTimers; 

class A 
{ 
public: 

    void AddItem(Foo& f, FooBar& fb) 
    { 
     CriticalSection::Guard g(lock_); 
     std::pair< MyList::iterator, bool > new_foo = 
      my_list_.insert(std::make_pair(f, fb)); 
     if(new_foo.second) 
     { 
      timers_.insert(std::make_pair( 
       new_foo.first, 
       boost::make_shared<Timer>(FiveMinutes, boost::bind(&A::OnAgeTimer, this, new_foo.first)))); 
     } 
    }; 

    void OnAgeTimer(MyList::iterator item) 
    { 
     CriticalSection::Guard g(lock_); 

     // erase by key-type generates an error: 
     // functional(143) : error C2676: binary '<' : 'const std::_Tree<_Traits>::iterator' does not define this operator or a conversion to a type acceptable to the predefined operator 
     timers_.erase(item); 

     // erase by iterator. works okay. 
     my_list_.erase(item); 
    }; 

private: 
    MyList my_list_; 
    MyListAgeTimers timers_; 
    CriticalSection lock_; 
}; 

你不能使用一個映射的迭代器作爲鍵類型到另一個嗎?或者,我需要爲此定義專門的operator<嗎?

編輯:

顯而易見的事情(我)就是這樣的:

namespace std { 
inline bool operator <(const MyList::iterator& a, const MyList::iterator& b) 
{ 
    return a->first < b->first; 
} 
}; 

但是,如果這是正確的,這是爲什麼比較時沒有爲std::operator<的默認行爲兩個迭代器?

回答

6

std::map<key, value>要求keyoperator<;這就是地圖對象用來查找匹配鍵的地方。 std::map<x, y>::iterator是一個雙向迭代器;它沒有operator<,因此除非您提供自己的operator<或函數對象來比較兩個迭代器並確定哪個先於另一個映射,否則不能將其用作另一個映射中的鍵類型。

+1

+1:使用迭代器作爲「map」關鍵字的想法讓我感到畏縮,如果小心謹慎地使用它,它可能會有用處。 –

+0

+1在句子中使用分號 – PaulH

+0

@JohnDibling - 我同意,但沒有提到它,因爲它看起來像在這裏被合理地處理(除了'operator <')。 –

相關問題