简体   繁体   English

为什么std :: map有一个find成员函数?

[英]Why does std::map have a find member function?

A colleague and I were discussing the relative merits of member vs. non-member functions. 我和一位同事正在讨论成员与非成员职能的相对优点。 A question arose: why does std::map have a find member function. 出现了一个问题:为什么std::map有一个find成员函数。

My answer was that although you can use std::find on maps, you must search for the key-value pair, or use find_if and eg a lambda. 我的回答是,尽管你可以在地图上使用std::find ,但你必须搜索键值对,或者使用find_if和例如lambda。 However, this is linear and map.find offers a search by key in better than linear time. 但是,这是线性的, map.find提供了一个比密钥更好的线性时间搜索。 I ended with the assertion that if it could have been a non-member, then it would have been! 我最后断言,如果它可能是一个非成员,那么它本来就是! (Although, std::string suggests that I might have been somewhat hasty in my generalization). (虽然,std :: string表明我的概括可能有些仓促)。

My colleague pointed out that it would be possible to implement find the same way as a non-member function using map.lower_bound . 我的同事指出,使用map.lower_bound可以实现与非成员函数相同的find方式。

Is there a rationale for map.find having been made a member? map.find有没有理由成为会员?

A big objection to implementing std::find searching for a key on std::map as a non-member function is that doing so would prevent you from implementing the current version of std::find , which searches for a key-value pair. 实现std::find搜索std::map上的键作为非成员函数的一个很大的反对意见是这样做会阻止你实现当前版本的std::find ,它会搜索一个键值对。

Being an associative container, std::map contains key-value pairs. 作为关联容器, std::map包含键值对。 Non-member std::find is defined for all containers as a function that searches for an item in the container, which must be a key-value pair for std::map ; 非成员std::find是为所有容器定义的,它是一个搜索容器中项目的函数,它必须是std::map的键值对; using std::find to look up an item by its key would be inconsistent. 使用std::find通过其键查找项目将是不一致的。

Obviously, one could implement std::find_by_key function applicable only to maps, but such function would always have a specialization based on the type of map. 显然,可以实现仅适用于地图的std::find_by_key函数,但是这样的函数总是具有基于地图类型的特化。 This provides no improvement in the API design over adding a member-function. 与添加成员函数相比,API设计没有改进。

My colleague pointed out that it would be possible to implement find the same way as a non-member function using map.lower_bound . 我的同事指出,使用map.lower_bound可以实现与非成员函数相同的find方式。

This would lead to inconsistency across different types of maps. 这将导致不同类型的地图之间的不一致。 For instance, you cannot implement a free function find using the lower_bound member function for std::unordered_map , since there is no such member function (same for google::dense_hash_map etc.). 例如,您无法使用std::unordered_maplower_bound成员函数实现自由函数find ,因为没有这样的成员函数(对于google::dense_hash_map等也是如此)。 Efficient find for unordered_map needs access to class internals and needs to know its implementation details. 有效find unordered_map需要访问类内部,并需要知道其实现细节。 Then, you would end up with map not having find member function and unordered_map having one. 然后,你最终得到的map没有find成员函数而unordered_map有一个。 This would make hard to write a generic code that would allow user to choose between different types of maps, such as: 这将很难编写允许用户在不同类型的地图之间进行选择的通用代码,例如:

template <class map_type>
void (const map_type & map) {
   // use std::find or map.find here ???

std::map has a member find because map::operator[] and map::at don't cover all the use cases for looking up by key. std::map有一个成员find因为map::operator[]map::at没有涵盖按键查找的所有用例。

operator[] requires the mapped_type be DefaultConstructible , and modifies the size of the map if it fails to find. operator[]要求mapped_typeDefaultConstructible ,如果找不到,则修改map的大小。

at throws if it fails to find. at投掷时如果找不到。

find doesn't have the restriction of operator[] , and neither modifies nor throws if it fails to find. find没有operator[]的限制,如果找不到,则既不修改也不抛出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM