我和一位同事正在讨论成员功能与非成员功能的相对优点。出现一个问题:std::map
为什么有一个find
成员函数。
我的回答是,尽管您可以在地图上使用std::find
,但必须搜索键值对,或使用find_if和。一个lambda。但是,这是线性的,map.find
比线性时间提供了更好的关键字搜索。我以断言结尾,那就是如果它可以是非成员,那就应该是! (不过,std :: string表示我的概括可能有些草率)。
我的同事指出,可以像使用find
的非成员函数一样来实现map.lower_bound
。
是否有理由map.find
成为会员?
答案 0 :(得分:8)
将std::find
搜索为std::map
上的键作为非成员函数的主要反对意见是,这样做会阻止您实现当前版本的std::find
,后者会进行搜索键值对。
作为std::map
的关联容器,包含键值对。为所有容器定义非成员std::find
的功能是搜索容器中的项目,该项目必须是std::map
的键值对;使用std::find
通过键查找项目会不一致。
很显然,可以实现仅适用于地图的std::find_by_key
功能,但是这种功能将始终具有基于地图类型的特殊化功能。与添加成员函数相比,这在API设计上没有任何改进。
答案 1 :(得分:3)
我的同事指出,可以像使用
find
的非成员函数一样来实现map.lower_bound
。
这将导致不同类型地图之间的不一致。例如,您无法使用find
的{{1}}成员函数来实现自由函数lower_bound
,因为没有这样的成员函数(与std::unordered_map
相同)。 google::dense_hash_map
的高效find
需要访问类内部,并且需要了解其实现细节。然后,您将得到unordered_map
没有map
成员函数和find
只有一个成员函数。这将使得很难编写通用代码,使用户可以在不同类型的地图之间进行选择,例如:
unordered_map
答案 2 :(得分:0)
std::map
拥有成员身份,因为map::operator[]
和map::at
并未涵盖按键查找的所有用例。
operator[]
要求mapped_type
为 DefaultConstructible ,并在找不到地图时修改地图的大小。
at
如果找不到则抛出。
find
没有operator[]
的限制,并且如果找不到也不会修改或抛出。