3

当我想用 STL 集合在 C++ 中存储自定义对象时,有很多人说:你应该重载 < 运算符,但如果我想使用 find() 方法,我认为它可以使用 == 运算符来实现。谁能给我一些指示?

4

4 回答 4

8

标准库 set::find使用等价而不是等价来查找值。您不需要提供operator ==, 只是operator <(或您为 指定的任何比较运算符setstd::less作为默认值)。

如果您想知道如何找到您的元素,那么假设默认排序find(x)将返回以下元素e

!( x < e || e < x )
于 2012-12-20T04:04:35.830 回答
1

由于std::sets 需要指定严格弱排序的东西。operator==不足以完成这项任务。

operator<只有当它对类有意义时,你才应该重载。如果没有,最好利用std::set具有作为第二个模板参数的事实Compare。因此,定义一个比较结构/函数并将其作为集合的第二个参数传递是另一个通常更可取的选项。

最后的选择是专门std::less针对您的类型。例如:

namespace std
{ 
    template <>
    struct less<CustomClass>
    { ... };
}
于 2012-12-20T04:06:30.153 回答
1

大多数标准库算法和容器使用 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==。

于 2012-12-20T04:07:02.360 回答
0

set, map,multiset并且multimap只使用你给他们的比较函数,默认为std::less,一般为operator<。C++11 中的无序版本有更复杂的协议;它们不需要顺序比较(它们是无序的),但它们需要相等和散列。

这也适用于所有涉及排序的标准算法(sortnth_elementlower_boundbinary_search等)。但是,该find 算法(以及其他类似的算法,例如countsearchmismatch等)确实需要一个相等函数,默认为operator==。没有标准库算法需要两者。

由于您特别询问了find成员函数,答案将是set所有成员函数只需进行顺序比较即可正常工作。

不过,如果您要定义operator<.

于 2012-12-20T04:05:33.167 回答