我可以使用什么作为 std::map 键?

发布于 2024-08-13 05:56:16 字数 749 浏览 3 评论 0原文

扩展

我有:

struct Coord
{
  int row, col ;

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

我正在尝试创建一个 map,您可以在其中通过 Coord 查找 Node*

问题是,它有错误。通过 Coordmap 的查找返回错误的结果。

我很难确定这是否合适。

维基百科说,map [keys] 需要严格的弱排序。我做错了吗?有没有办法让它工作,或者地图的键应该是可以“严格排序”的简单值?

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

Extends.

I have:

struct Coord
{
  int row, col ;

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

I'm trying to create a map<Coord, Node*>, where you can look up a Node* by Coord.

The problem is, it has bugs. Lookups into the map<Coord, Node*> by Coord are returning the wrong ones.

I'm having difficulty figuring out if this is appropriate or not.

Wikipedia says, map [keys] requires a strict weak ordering. Have I done this wrong? Is there a way to make it work, or should keys for a map be simple values that can be "strictly ordered"?

Basically the question is what is required for a custom struct to work as a key for my std::map?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

蒲公英的约定 2024-08-20 05:56:16

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

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

obj1 (this)
行:2
列:3

​​obj2
行:3
列:2

obj1 <对象2? => false

好吧 那么:

obj2 <对象1? => false

唯一的结论是它们必须相等(基于您的 < 运算符)。由于这是一张地图,并且键是唯一的,因此两个键都对应于同一位置。这种行为可能是也可能不是您所期望的,但听起来可能不是。

您需要的是在行/列之间设置优先级,以便 <确实如您所期望的那样工作:

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

Yes you could very well have a problem with strict-weak ordering. Odds are its not working like you'd expect. Consider:

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

obj1 (this)
row: 2
col: 3

obj2
row: 3
col: 2

obj1 < obj2? => false

ok well then:

obj2 < obj1? => false

The only conclusion is that they must be equal (based on your < operator). Since this is a map, and keys are unique, both keys reselve to the same spot. This behavior may-or-may not be what you expect, but it sounds like it probably isn't.

What you need is to make a precedence between row/col so that < really works like you'd expect:

  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;
  }
泼猴你往哪里跑 2024-08-20 05:56:16

您可能想要:

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

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

You probably want:

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

or vice versa. This one has bitten me a few times too!

冷夜 2024-08-20 05:56:16

试试这个:

struct Coord
{
  int row, col ;

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

    return col < other.col ;
  }
} ;

try this:

struct Coord
{
  int row, col ;

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

    return col < other.col ;
  }
} ;
明月松间行 2024-08-20 05:56:16
bool operator<(const Coord& other) const
{
    return row < other.row
        || row ==other.row
        && col < other.col;
}
bool operator<(const Coord& other) const
{
    return row < other.row
        || row ==other.row
        && col < other.col;
}
旧情勿念 2024-08-20 05:56:16

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

您的 operator< 未满足此要求。考虑 a = { 1, 3 },b = { 3, 2 },c = { 2, 1 }。在这种情况下,a < 都不是。 b,b< a 都为真,并且 a < 都不是c,c< a 为真。这意味着a和b是等价的并且a和c是等价的,但是显然c<1。 b 所以 b 和 c 不等价,从而表明等价不具有传递性。这就是为什么您的操作员<不适合将 Coord 用作 std::map 中的键。

For a comparison function to impose a strict weak ordering on the set of values for your object, one of the conditions is that equivalence must be transitive. a and b are said to be equivalent if (in C++ syntax) !(a < b) && !(b < a) is true.

Your operator< fails this requirement. Consider a = { 1, 3 }, b = { 3, 2 }, c = { 2, 1 }. In this case neither of a < b, b < a are true and neither of a < c, c < a are true. This means that a and b are equivalent and a and c are equivalent, however clearly c < b so b and c are not equivalent, thus showing that equivalence isn't transitive. This is why your operator< is not suitable for Coord to be used as a key in a std::map.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文