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

时间:2011-07-04 15:09:47

标签: c++ stl map key

我想将给定类的对象映射到另一个对象的对象。但是,我想要用作键的类不是由我编写的,而是一个带有一些值的简单struct。 std :: map命令它的内容,我想知道它是如何做到的,如果任何一个任意类可以用作一个键,或者是否需要定义一组需求(运算符和不需要的话)。

如果是这样,我可以为实现运算符map使用的类创建一个包装器。我只需要知道我需要首先实现什么,并且没有一个类found online的引用指定它们。

4 个答案:

答案 0 :(得分:61)

密钥所需要的只是它是可复制的和可分配的。 地图中的排序由第三个参数定义 template(以及构造函数的参数,如果使用的话)。这个 默认std::less<KeyType>,默认为<运算符, 但是没有要求使用默认值。只是写一个比较 运算符(最好是作为功能对象):

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

请注意,它必须定义严格的排序,即如果CmpMyType()( a, b )返回true,则CmpMyType()( b, a )必须返回false,如果 两者都返回false,元素被认为是相等的(成员) 相同的等价类)。

答案 1 :(得分:21)

您需要定义运算符&lt;,例如:

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;

    // Otherwise a are equal
    if ( l.b < r.b )  return true;
    if ( l.b > r.b )  return false;

    // Otherwise both are equal
    return false;
}

// 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 ));
}

答案 2 :(得分:3)

答案实际上在您链接的参考文献中,在“比较”模板参数的描述下。

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

答案 3 :(得分:2)

set相同:该类必须具有“小于”精神的严格排序。要么重载适当的operator<,要么提供自定义谓词。任何两个ab对象!(a<b) && !(b>a)将被视为相等。

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