【问题标题】:How to check if std::map contains a key without doing insert?如何在不插入的情况下检查 std::map 是否包含键?
【发布时间】:2011-04-22 15:27:12
【问题描述】:

我发现检查重复项的唯一方法是插入并检查std::pair.secondfalse,但问题是如果密钥未使用,这仍然会插入一些东西,而我想要的是@987654324 @函数。

【问题讨论】:

标签: c++ stl map


【解决方案1】:

使用my_map.count( key );它只能返回 0 或 1,这本质上是您想要的布尔结果。

或者my_map.find( key ) != my_map.end() 也可以。

【讨论】:

  • @John:这有点过早优化的味道。在 GCC(我相信最合理的系统)上,map::count 被实现为find(__x) == end() ? 0 : 1;。对于multimap,您可能有性能争论,但这不是 OP 的问题,我仍然更喜欢优雅。
  • 不,过早的优化参数只有在优化需要一些努力时才有效,在这种情况下它不会。
  • 不正确。如果它使代码更易于阅读或消除不必要的开销,这还为时过早。在这种情况下,如果 count() 无论如何是通过 find() 实现的,那么直接调用 find() 就可以消除函数调用......所以,它是 mature 优化。我发现使用 find() 调用也更明显,但这纯粹是个人喜好。
  • 在习惯使用库函数之前了解它们的性能并不是一个过早的优化。在这种情况下,你是对的,这并不重要,但 find 和 count 之间的微小风格差异也没有关系。我认为您将“过早的优化”言辞太过分了。您应该采取任何可以找到的“免费”优化习惯并将其用于日常开发。当编码人员屈服于在可读性/开发时间/等方面付出成本的陷阱时,所有这些都是为了无法衡量的“性能提升”,过早的优化言论成为正确的建议。
  • 太远了,std 应该像地球上所有其他理智的地图类一样添加该死的has(k) / contains(k)。界面设计差。 find() 方法过于冗长,count(k) 方法在语义上与has(k) 绝对不一样。就此而言,find(k) 也不是。查看此问题的观看次数。
【解决方案2】:

Potatoswatter 的回答没问题,但我更喜欢用findlower_bound 代替。 lower_bound 特别有用,因为返回的迭代器随后可用于提示插入,如果您希望插入具有相同键的内容。

map<K, V>::iterator iter(my_map.lower_bound(key));
if (iter == my_map.end() || key < iter->first) {    // not found
    // ...
    my_map.insert(iter, make_pair(key, value));     // hinted insertion
} else {
    // ... use iter->second here
}

【讨论】:

  • 这与他所说的方式略有不同......唯一的区别是如果不需要插入,则可以跳过value的计算。
  • 当然,我知道 OP 不关心插入,所以基于 lower_bound 的解决方案是矫枉过正。我刚刚提到了我的回答“为了完整性”;就像我说的,你的完全足够了。 :-)
  • 是的,这是一个很好的答案,我不反对任何事情。只是先验地指出与insert 替代方案的关系。实际上,如果使用multimap,还有另一个区别,lower_bound 方法插入等效范围的开头,而普通的insert 方法添加到范围的末尾。
  • 不是问题的答案,但我的糟糕问题让我在这里找到了正确的答案......我需要进行插入/更新。 :D
  • @Hunter 你能告诉我你的代码吗?如果它不是很大,我可能会为您审查它。
【解决方案3】:

您的需求map.contains(key) 计划用于标准草案C++2a。 2017年由gcc 9.2实施。它也在当前的clang中。

【讨论】:

  • 这是一个不错的功能!我认为它已经登陆 C++20。 cppreference.com
猜你喜欢
  • 1970-01-01
  • 2014-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
  • 2012-12-12
相关资源
最近更新 更多