我有一个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<
的默认行为?
答案 0 :(得分:6)
std::map<key, value>
要求key
拥有operator<
;这就是地图对象用来查找匹配键的内容。 std::map<x, y>::iterator
是一个双向迭代器;它没有operator<
,所以除非你提供自己的operator<
或一个函数对象来比较两个迭代器并决定哪一个来自之前,否则不能将它用作另一个映射中的键类型其他