operator==
是不可避免的std::map::find()
这就是你犯了严重错误的地方。map
不使用operator==
无论如何,这并不是“不可避免的”。两把钥匙x
and y
就地图而言,如果!(x < y) && !(y < x)
.
map
不知道也不关心你是否已经实现operator==
。即使有,也不必是顺序中所有等效键都相等的情况operator==
.
所有这一切的原因是,只要 C++ 依赖顺序(排序、映射、集合、二分搜索),它所做的一切都基于“严格弱顺序”这一易于理解的数学概念,该概念也在标准中定义。没有特别需要operator==
,如果您查看这些标准函数的代码,您不会经常看到类似的内容if (!(x < y) && !(y < x))
这使得两个测试紧密结合。
此外,这些都不一定基于operator<
。默认比较器为map
is std::less<KeyType>
,默认情况下使用operator<
。但如果你有专门的std::less
for KeyType
那么你不需要定义operator<
,如果您为地图指定不同的比较器,那么它可能有也可能没有任何关系operator<
or std::less<KeyType>
。所以我说过的地方x < y
上面,确实是cmp(x,y)
, where cmp
是严格的弱顺序。
这种灵活性是不拖拉的另一个原因operator==
进去。认为KeyType
is std::string
,并且您指定自己的比较器来实现某种特定于区域设置的、不区分大小写的排序规则。如果map
used operator==
有时,那么这将完全忽略这样一个事实:仅大小写不同的字符串应该被视为相同的键(或在某些语言中:与出于排序目的而被认为无关紧要的其他差异)。所以平等比较会also必须是可配置的,但程序员只能提供一个“正确”答案。这不是一个好情况,您永远不希望您的 API 提供看起来像定制点但实际上并非如此的东西。
此外,这个概念是,一旦你排除了树中小于你正在搜索的键的部分,以及树中键小于它的部分,剩下的都是空的(没有找到匹配)或者其中有一个密钥(找到匹配)。所以,你已经使用过current < key
then key < current
,除了等价之外没有其他选择。情况恰恰是:
if (search_key < current_element)
go_left();
else if (current_element < search_key)
go_right();
else
declare_equivalent();
你的建议是:
if (search_key < current_element)
go_left();
else if (current_element < search_key)
go_right();
else if (current_element == search_key)
declare_equivalent();
这显然是不需要的。事实上,它是your建议效率较低!