我有一个包含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”,但遗憾的是它没有任何关于此的说法。
感谢您的回复。
答案 0 :(得分:11)
如果您只是将两个小部件相互比较,请使用成员operator <
。如果您要将Widget与其他内容进行比较,请定义全局operator <
(两个参数版本,可选择Widget类的朋友,但这是一个单独的问题。
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
。