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

Kia*_*ian 70 c++ stl key map

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

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

Jam*_*nze 63

密钥所需要的只是它是可复制的和可分配的.映射中的排序由模板的第三个参数(以及构造函数的参数,如果使用)定义.该 默认std::less<KeyType>,其默认为<运营商,但没有规定使用默认值.只需编写一个比较运算符(最好作为一个功能对象):

struct CmpMyType
{
    bool operator()( MyType const& lhs, MyType const& rhs ) const
    {
        //  ...
    }
};
Run Code Online (Sandbox Code Playgroud)

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

  • @nurdglaw 我最近看到一个演讲,其中一位大师咆哮着为每个班级提供一个 `operator&lt;`。他举了椅子的例子。您可以按高度、腿数甚至颜色对它们进行排序,但是您选择的任何东西都是完全任意的,实际上椅子没有自然排序,而是必须选择椅子的容器下令。很多时候,一个看似显而易见的选择的`operator&lt;`实际上只是众多可能性中的一个,因此不属于这个类......沿着这条线是他的推理。 (2认同)

BЈо*_*вић 22

您需要定义operator <,例如:

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 ));
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个糟糕的比较运算符。 (2认同)