【问题标题】:Defining < for STL sort algorithm - operator overload, functor or standalone function?为 STL 排序算法定义 < - 运算符重载、仿函数或独立函数?
【发布时间】:2011-01-27 01:26:43
【问题描述】:

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

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

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

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

b.定义一个带有两个 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》一书,但不幸的是它对此没有什么可说的。

感谢您的回复。

【问题讨论】:

  • 看来我错过了 Effective STL 的第 46 条。它说更喜欢仿函数而不是成员函数,因为它可以更容易地内联。
  • 我知道执行选项 A(类的成员函数)要容易一些。但是你应该将这个论点与什么进行比较?一个简单的return (x&lt;y),其中 y 是参数不起作用...至少对我来说不是,我遇到了段错误。

标签: c++ sorting stl operator-overloading functor


【解决方案1】:

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

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

如果“小于”在您的课程上下文中没有意义,那么请不要为您的课程重载“运算符Widget::Compare。

【讨论】:

    【解决方案2】:

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

    我更喜欢函子。

    【讨论】:

    • 是否直观无关紧要,适用于定义比较器的任何方法。您所需要的只是一个合理的比较。
    • 我的意思是任何人都可以比较某些实体(浮点数、整数、字符串、复数、长数字..),而某些实体则不能 - 在这种情况下,我使用的是比较函数/仿函数,例如WidgetByXCoordinateComparator、WidgetByNameComparator 等
    • 一般来说,只有在所有人都能直观理解时才使用运算符重载是一种很好的做法。
    【解决方案3】:

    如果您只是比较两个小部件,请使用成员operator &lt;。如果您将 Widget 与其他东西进行比较,请定义一个全局 operator &lt;(两个参数版本,可选 Widget 类的朋友,但这是一个单独的问题。

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

    【讨论】:

    • +1。运算符重载的最重要规则是如果没有意义就不要这样做。
    【解决方案4】:

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

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

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

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

    请注意,您无需继承 binary_operator 即可使其工作,尽管它确实为您提供了一些不错的 typedefs。

    【讨论】:

    • 感谢您的评论。我没有意识到函子是否需要 binary_operator 才能工作 - 无论如何我总是将它包含在我的程序中。如果 Effective STL item 46 正确,您对性能的评论可能不正确(函子中的函数可以内联)。
    猜你喜欢
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    相关资源
    最近更新 更多