如何检查std :: map是否包含一个没有插入的键?

jma*_*erx 140 c++ stl map

我发现检查重复项的唯一方法是插入并检查std::pair.secondfor false,但问题是如果密钥未使用,这仍会插入一些东西,而我想要的是一个map.contains(key);函数.

Pot*_*ter 291

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

另外my_map.find( key ) != my_map.end()也可以.

  • @John:过早优化的臭味.在GCC(我确定最合理的系统),`map :: count`实现为`find(__ x)== end()?0:1;`.对于`multimap`,你可能有一个性能参数,但这不是OP的问题,我仍然更喜欢优雅. (38认同)
  • 不,过早优化参数仅在优化需要一些努力时才有效,在这种情况下它不会. (37认同)
  • 不对.如果它使代码更容易阅读或消除不必要的开销,那么为时尚早.在这种情况下,如果count()无论如何都是通过find()实现的,那么调用find()会直接消除函数调用... ergo,它是_mature_ optimization.我发现使用find()调用也更加明显,但这纯粹是个人偏好. (12认同)
  • -1:应该使用`find`.它至少与地图和多地图的"count"一样有效,并且当您考虑到对找到的键进行更改的典型需求时效率更高. (8认同)
  • 在养成使用它们的习惯之前,了解库函数的性能并不是一个不成熟的优化.在这种情况下,你是对的,没关系,但是查找和计数之间的微小风格差异也没有.我认为你过分采用"过早优化"的言论.你应该采取任何你能找到的"免费"优化习惯,并将它们用于日常开发.当编码人员屈服于在可读性/开发时间等方面支付成本的陷阱时,所有这些都是为了获得不可测量的"性能提升",即过早的优化修辞成为正确的建议. (8认同)
  • 远远的,std应该添加一个该死的`has(k)`/`contains(k)`就像这个星球上的其他每个理智的地图类一样.界面设计不佳.find()方法过于冗长,而`count(k)`方法肯定与`has(k)`没有语义平价.就此而言,"find(k)"也不是.查看此问题的查看次数. (8认同)
  • @VoidStar <响应被优化了> (6认同)
  • 我发现`my_map.count(key)> 0`更能代表"这个键出现在地图中吗?" 比`my_map.find(key)!= my_map.end()`.@JohnDibling说"当你需要进行更改时效率更高",我会说,"如果你需要使用找到的密钥,保存它并测试`end()`.如果你只需要检查存在,请使用`count`".针对不同需求的不同方法有助于提高可读性. (5认同)
  • 从风格上来说,我喜欢 if(theMap.count(key)) {...} 就很好。对我来说看起来像哈斯奇! (2认同)
  • .find( ... ) 在整个 C++ 库中广泛使用,实践者应该熟悉它。_find_ 比 _count_ 更好地表达了意图。C++20 将用显式的 _contains_ 来澄清事情 https://en.cppreference.com/w/cpp/container/map/contains (2认同)
  • 如果标准委员会可以向 C++ 添加线程(以及大部分厨房水槽),那么他们肯定可以向 std::map 添加 contains() 方法。“纯洁”在十年前就消失了。 (2认同)

Chr*_*ung 46

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

  • +1这个额外的答案是教育性的 (7认同)
  • 是的,这是一个很好的答案,我不同意任何意见.只是指出与`insert`先验替代的关系.实际上,如果使用`multimap`,还有另一个区别,`lower_bound`方法在等效范围的开头插入,而普通`insert`方法添加到范围的末尾. (4认同)
  • 不是问题的答案,但我糟糕的问题让我在这里找到了正确的答案......我需要进行插入/更新。:D (2认同)

Cam*_*une 17

您的愿望,map.contains(key),已安排在标准草案C++2a 中。2017 年由gcc 9.2实现。它也在当前的clang 中

  • 这是一个很好的功能!我认为它已经登陆C++20了。[cppreference.com](https://en.cppreference.com/w/cpp/container/map/contains) (2认同)