定义<用于STL排序算法 - 运算符重载,仿函数还是独立函数?

时间:2010-03-13 00:21:34

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

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

为了使分类起作用,必须定义一个比较两个Widget对象的比较器。似乎有无数种方法可以做到这一点。从我可以收集到的,可以:

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

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

湾定义一个带有两个小部件的独立函数:

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

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

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

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

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

有谁知道哪种方法更好?特别是我有兴趣知道我是否应该做1或2.我搜索了Scott Meyer的书“有效STL”,但遗憾的是它没有任何关于此的说法。

感谢您的回复。

4 个答案:

答案 0 :(得分:11)

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

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

答案 1 :(得分:2)

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

我更喜欢仿函数。

答案 2 :(得分:1)

它们在性能方面应该都是相同的,但它们之间还存在其他差异:

  • 前两个保存你必须明确指定比较器,并且可以很容易地与其他操作一起使用,可能是定义不明确但不允许明确指定比较器的操作。

  • 只有仿函数允许其他数据进行比较。例如,如果您要比较int s,则可以创建一个比较,比较它们与第三个点P的距离,它将是仿函数实例的成员。

  • Functors通常不太容易阅读(不熟悉C ++的人)。

请注意,您无需继承binary_operator即可使用它,但它确实为您提供了一些不错的typedef

答案 3 :(得分:1)

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

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

如果“小于”在你的课程中没有任何意义,那么请不要重载“operator&lt;”为你的班级。这会让用户感到困惑。使用c。相反,要么使它成为一个嵌套类,要么在类中键入它,这样你就可以把它写成Widget::Compare