【问题标题】:What _can_ I use as std::map keys?我可以使用什么作为 std::map 键?
【发布时间】:2010-12-23 19:37:33
【问题描述】:

Extends.

我有:

结构坐标 { 整数行,列; bool operator

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

问题是,它有错误。 Coordmap<Coord, Node*> 的查找返回了错误的结果。

我很难确定这是否合适。

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

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

【问题讨论】:

  • 您能否更具体地了解“有错误”?你的代码编译了吗?返回错误的结果?崩溃?
  • std::map 没有任何错误。至少在我见过的 MS STL 中。维基百科也不是 RTFN 的最佳来源。
  • 我所说的“有错误”只是下面的句子:“Coord 对地图 的查找返回的是错误的。”

标签: c++ stl map key


【解决方案1】:

你可能想要:

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

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

【讨论】:

  • 感谢您的接受,但我认为 Doug T 的回答要好得多,包括我写的内容。
  • 嗯,你的回答了这个问题,而且更早。但我会改变它。
【解决方案2】:

试试这个:

struct Coord
{
  int row, col ;

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

    return col < other.col ;
  }
} ;

【讨论】:

    【解决方案3】:

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

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

    obj1(这个) 行:2 列:3

    obj2 行:3 列:2

    obj1 错误

    那好吧:

    obj2 错误

    唯一的结论是它们必须相等(基于您的

    您需要在 row/col 之间设置优先级,以便

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

    【讨论】:

    • 否则return row &lt; other.row || (row == other.row &amp;&amp; col &lt; other.col)
    • 问题不仅在于比较可能无法达到预期效果,还在于原始定义下的等价关系不是等价关系,这违反了用作std::map 中的键。
    • +1,这就是为什么专业人士使用tie(col, row) &lt; tie(other.col, other.row) ;)
    【解决方案4】:
    bool operator<(const Coord& other) const
    {
        return row < other.row
            || row ==other.row
            && col < other.col;
    }
    

    【讨论】:

    • 不使用== 操作符更正确。要将两个元素与operator&lt; 进行比较,它们应该只需要定义operator&lt;
    • @GMan 我们在这里讨论的是比较整数。
    • 如何用括号明确 && 的优先级高于 ||?
    • @Neil 在摘要中这是一个非常好的观点。你不希望你的代码因为你改变了底层类型而中断。
    • 不,它没有,但我确实尝试使底层类型的要求最小化。如果你在这里只使用
    【解决方案5】:

    要让比较函数对对象的值集进行严格的弱排序,其中一个条件是等价性必须是可传递的。如果(在 C++ 语法中)!(a &lt; b) &amp;&amp; !(b &lt; a) 为真,则 ab 被认为是等价的。

    您的operator&lt; 不符合此要求。考虑 a = { 1, 3 }, b = { 3, 2 }, c = { 2, 1 }。在这种情况下,a Coord 用作 std::map 中的键。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-06
      • 2011-06-23
      • 1970-01-01
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 2017-03-16
      • 1970-01-01
      相关资源
      最近更新 更多