什么_can_我用作std :: map键?

时间:2009-12-06 21:02:50

标签: c++ stl map key

Extends

我有:

struct Coord
{
  int row, col ;

  bool operator<( const Coord& other ) const
  {
    return row < other.row && col < other.col ;
  }
} ;

我正在尝试创建map<Coord, Node*>,您可以在Node*之间查找Coord

问题是,它有错误。 map<Coord, Node*> Coord的查询正在返回错误的内容。

我很难弄清楚这是否合适。

维基百科说,map [keys] requires a strict weak ordering。我做错了吗?有没有办法使它工作,或者地图的键是否可以“严格排序”的简单值?

基本上问题是自定义struct作为我的std :: map的关键字需要什么?

5 个答案:

答案 0 :(得分:19)

是的,您可能会遇到严格弱序的问题。赔率是它没有像你期望的那样工作。考虑:

  bool operator<( const Coord& other ) const
  {
    return row < other.row && col < other.col ;
  }

obj1(这个) 行:2 col:3

OBJ2 行:3 col:2

obj1&lt; obj2的? =&GT;假

好吧那么:

obj2&lt; OBJ1? =&GT;假

唯一的结论是它们必须相等(基于你的&lt;运算符)。由于这是一张地图,并且按键是唯一的,因此两个按键都会重新连接到同一个地点。这种行为可能或者可能不是你所期望的,但听起来可能不是。

你需要的是在row / col之间建立一个优先级,以便&lt;真的像你期望的那样:

  bool operator<( const Coord& other ) const
  {
     // look at row first, if row is equal, check column.
     if (row < other.row)
     {
         return true;
     }
     else if (row == other.row)
     {
         return col < other.col ;
     }
     return false;
  }

答案 1 :(得分:6)

你可能想要:

 bool operator<( const Coord& other ) const
  {
    if ( row < other.row ) {
       return true;
    }
    else if ( row == other.row ) {
       return col < other.col;
    }
    else {
       return false ;
    }
  }

反之亦然。这个也咬我几次了!

答案 2 :(得分:1)

试试这个:

struct Coord
{
  int row, col ;

  bool operator<( const Coord& other ) const
  {
    if (row != other.row)
      return row < other.row;

    return col < other.col ;
  }
} ;

答案 3 :(得分:0)

bool operator<(const Coord& other) const
{
    return row < other.row
        || row ==other.row
        && col < other.col;
}

答案 4 :(得分:0)

对于比较函数,对对象的值集强加一个严格的弱排序,其中一个条件是等价必须是可传递的。如果(在C ++语法中)a为真,则b!(a < b) && !(b < a)被认为是等效的。

您的operator<未达到此要求。考虑a = {1,3},b = {3,2},c = {2,1}。在这种情况下,两者都不是&lt; b,b&lt; a是真的而且都不是&lt; c,c&lt;一个是真的。这意味着a和b是等价的,a和c是等价的,但显然c <1。 b所以b和c不等价,因此表明等价不是传递的。这就是您的运营商&lt;不适合Coord用作std::map中的密钥。