当我想用 STL 集合在 C++ 中存储自定义对象时,有很多人说:你应该重载 < 运算符,但如果我想使用 find() 方法,我认为它可以使用 == 运算符来实现。谁能给我一些指示?
4 回答
标准库 set::find
使用等价而不是等价来查找值。您不需要提供operator ==
, 只是operator <
(或您为 指定的任何比较运算符set
,std::less
作为默认值)。
如果您想知道如何找到您的元素,那么假设默认排序find(x)
将返回以下元素e
:
!( x < e || e < x )
由于std::set
s 需要指定严格弱排序的东西。operator==
不足以完成这项任务。
operator<
只有当它对类有意义时,你才应该重载。如果没有,最好利用std::set
具有作为第二个模板参数的事实Compare
。因此,定义一个比较结构/函数并将其作为集合的第二个参数传递是另一个通常更可取的选项。
最后的选择是专门std::less
针对您的类型。例如:
namespace std
{
template <>
struct less<CustomClass>
{ ... };
}
大多数标准库算法和容器使用 operator<(或您提供的比较函数,如果 lhs 元素较小,则返回 true)进行排序和搜索。用于无序容器的算法将使用 operator==。
例如,std::lower_bound() 将返回与排序容器中的搜索条件匹配的第一个元素,如果未找到确切的项,则最大元素仍小于搜索项,或者返回容器末尾的迭代器如果没有元素大于您搜索的内容。它使用 operator< 执行此操作,不需要其他运算符。它需要 log(n) 顺序的许多操作。
除了 != 和 == 之外,所有其他比较运算符(>、>=、<=)都可以从 operator< 派生。
然而,std::find 要求使用的类型是 Equality Comparable。您可以在此处找到参考:http: //en.cppreference.com/w/cpp/algorithm/find
因此,如果您正在使用有序元素,则需要 operator<。如果您使用无序元素,则需要 operator==。
set
, map
,multiset
并且multimap
只使用你给他们的比较函数,默认为std::less
,一般为operator<
。C++11 中的无序版本有更复杂的协议;它们不需要顺序比较(它们是无序的),但它们需要相等和散列。
这也适用于所有涉及排序的标准算法(sort
、nth_element
、lower_bound
、binary_search
等)。但是,该find
算法(以及其他类似的算法,例如count
、search
、mismatch
等)确实需要一个相等函数,默认为operator==
。没有标准库算法需要两者。
由于您特别询问了find
成员函数,答案将是set
所有成员函数只需进行顺序比较即可正常工作。
不过,如果您要定义operator<
.