10

我有一个 stl::list 包含 Widget 类对象。它们需要根据 Widget 类中的两个成员进行排序。

为了使排序工作,必须定义一个比较两个 Widget 对象的小于比较器。似乎有无数种方法可以做到这一点。据我所知,一个人可以:

一种。在类中定义一个比较运算符重载:

bool Widget::operator< (const Widget &rhs) const

湾。定义一个带有两个 Widget 的独立函数:

bool operator<(const Widget& lhs, const Widget& rhs);

然后让 Widget 类成为它的朋友:

class Widget {
    // Various class definitions ...
    friend bool operator<(const Widget& lhs, const Widget& rhs);
};

C。定义一个仿函数,然后在调用排序函数时将其作为参数包含在内:

class Widget_Less :
public binary_function<Widget, Widget, bool> { 
    bool operator()(const Widget &lhs, const Widget& rhs) const;
};

有人知道哪种方法更好吗?特别是我很想知道我应该做 1 还是 2。我搜索了 Scott Meyer 的《Effective STL》一书,但不幸的是,它对此没有什么可说的。

感谢你的回复。

4

4 回答 4

11

如果您只是将两个 Widget 相互比较,请使用 member operator <。如果您将 Widget 与其他东西进行比较,请定义一个全局operator <(两个参数版本,可选 Widget 类的朋友,但这是一个单独的问题。

只有当你做一些不那么正统的事情时,你才真正想要的函子。如果“小于”比较在小部件的上下文中没有意义,请选择一个仿函数。在这种情况下,拥有operator <可能会令人困惑。当然,函子仍然必须提供一个排序,但仅仅因为它是一个排序并不意味着它是一个“小于”操作。(例如,对于函子来说,按人口排序状态可能比operator <.

于 2010-03-13T00:28:48.470 回答
2

ab 两个小部件的比较运算符对我来说并不直观。现在我看不出它能做什么。此外,如果您需要一个新的比较运算符时此功能不直观,那么在这种情况下您可以做什么?

我更喜欢函子。

于 2010-03-13T00:26:13.590 回答
1

它们在性能方面应该都是相同的,但它们之间还有其他区别:

  • 前两个使您不必显式指定比较器,并且可以轻松地与其他操作一起使用,可能定义不明确的操作不允许显式指定比较器。

  • 只有函子允许附加数据进行比较。例如,如果您正在比较ints,您可以创建一个比较来比较它们与第三个点 P 的距离,该点将是函子实例的成员。

  • 函子通常不太容易阅读(对于那些不熟悉 C++ 的人)。

注意,你不需要继承binary_operator它就可以工作,尽管它确实给了你一些不错typedef的 s。

于 2010-03-13T00:26:28.037 回答
1

对于大多数目的,a。和 b。是相同的。所以真正的问题是,什么时候用a/b,什么时候用c。

答案是:如果“小于”明确地对您的对象有意义,则使用 a 或 b。如果您的班级是数字,请使用<.

如果“小于”在您的班级上下文中没有意义,那么请不要为您的班级重载“operator<”。它会使用户感到困惑。使用 c。取而代之,要么将其设为嵌套类,要么在您的类中对其进行 typedef,这样您就可以将其编写为Widget::Compare.

于 2010-03-13T00:41:35.243 回答