map键类必须满足哪些要求才能成为有效的键

What requirements must std::map key classes meet to be valid keys?

本文关键字:能成为 有效 满足 map      更新时间:2023-10-16

我想把一个给定类的对象映射到另一个类的对象。但是,我要用作键的类不是我编写的,它是一个具有几个值的简单struct。std::map排序它的内容,我想知道它是如何做到的,如果任何任意类可以用作键,或者是否有一组需要定义的需求(操作符等)。

如果是这样,我可以为实现操作符映射使用的类创建一个包装器。我只需要知道我首先需要实现什么,并且我在网上找到的类的引用都没有指定它们。

所需要的键是可复制和可分配的。类的第三个参数定义映射中的顺序模板(以及构造函数的实参,如果使用的话)。这默认std::less<KeyType>,默认为<操作符;但是不要求使用默认值。写一个比较操作符(最好作为函数对象):

struct CmpMyType
{
    bool operator()( MyType const& lhs, MyType const& rhs ) const
    {
        //  ...
    }
};

注意它必须定义一个严格的顺序,即如果CmpMyType()( a, b )返回true,那么CmpMyType()( b, a )必须返回false,如果都返回false,这两个元素被认为是相等的

需要定义操作符<,例如:

struct A
{
  int a;
  std::string b;
};
// Simple but wrong as it does not provide the strict weak ordering.    
// As A(5,"a") and A(5,"b") would be considered equal using this function.
bool operator<(const A& l, const A& r )
{
  return ( l.a < r.a ) && ( l.b < r.b );
}
// Better brute force.
bool operator<(const A& l, const A& r )
{ 
    if ( l.a < r.a )  return true;
    if ( l.a > r.a )  return false;
    // a are equal, compare b
    return ( l.b < r.b );
}
// This can often be seen written as
bool operator<(const A& l, const A& r )
{
   // This is fine for a small number of members.
   // But I prefer the brute force approach when you start to get lots of members.
   return ( l.a < r.a ) ||
          (( l.a == r.a) && ( l.b < r.b ));
}
 

答案实际上在你链接的参考中,在"Compare"模板参数的描述下。

唯一的要求是Compare(默认为less<Key>,默认使用operator<来比较键)必须是"严格弱排序"

set相同:类必须按照"小于"的精神严格排序。要么重载一个适当的operator<,要么提供一个自定义谓词。任意两个对象ab,且!(a<b) && !(b>a)被认为是相等的

map容器实际上将按照该排序提供的顺序保留所有元素,这就是您如何通过键值实现O(log n)查找和插入时间的方法。