我有一个包含 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》一书,但不幸的是它对此没有任何说明。
感谢你的回复。
I have a stl::list containing Widget class objects. They need to be sorted according to two members in the Widget class.
For the sorting to work, a less-than comparator comparing two Widget objects must be defined. There seems to be a myriad of ways to do it. From what I can gather, one can either:
a. Define a comparison operator overload in the class:
bool Widget::operator< (const Widget &rhs) const
b. Define a standalone function taking two Widgets:
bool operator<(const Widget& lhs, const Widget& rhs);
And then make the Widget class a friend of it:
class Widget {
// Various class definitions ...
friend bool operator<(const Widget& lhs, const Widget& rhs);
};
c. Define a functor and then include it as a parameter when calling the sort function:
class Widget_Less :
public binary_function<Widget, Widget, bool> {
bool operator()(const Widget &lhs, const Widget& rhs) const;
};
Does anybody know which method is better? In particular I am interested to know if I should do 1 or 2. I searched the book Effective STL by Scott Meyer but unfortunately it does not have anything to say about this.
Thank you for your reply.
发布评论
评论(4)
如果您仅比较两个 Widget,请使用成员
运算符 <
。如果您将 Widget 与其他东西进行比较,请定义一个全局运算符 <
(两个参数版本,可选 Widget 类的友元,但这是一个单独的问题。您真正需要的函子,如果您是如果“小于”比较在小部件的上下文中没有意义,则选择一个不太正统的事情,在这种情况下,使用
运算符<
当然可能会令人困惑。函子仍然必须提供排序,但仅仅因为它是一个排序并不意味着它是一个“小于”操作(例如,对于函子来说,按人口对状态进行排序可能比运算符更好。
。If you are only comparing two Widgets to each other, use a member
operator <
. If you are comparing Widget to something else, define a globaloperator <
(the two parameter version, optionally a friend of the Widget class but that is a separate issue.Functor you really only want if you are doing something a little less orthodox. Choose a functor if a "less than" comparison doesn't make sense in the context of widgets. In that case, having
operator <
could be confusing. Of course, functors still have to provide an ordering, but just because it is an ordering doesn't really mean it is a "less than" operation. (Example, sorting states by population is probably better for a functor than anoperator <
.ab 对我来说,两个小部件的比较运算符并不直观。现在我看不出它能做什么。
另外,如果这个函数不直观,一旦您需要一个新的比较运算符,在这种情况下您可以做什么?
我更喜欢函子。
a. b. Comparison operator for two Widgets is not intuitive thing as for me. Now I can't see what it can do.
Also if this function is not intuitive once you will need one new comparison operator, what you can do in this case?
I prefer functor.
它们在性能方面应该是相同的,但它们之间还存在其他差异:
前两个使您不必显式指定比较器,并且可以轻松地与其他操作一起使用,可能是定义不明确的操作不允许显式指定比较器。
只有函子允许使用附加数据进行比较。例如,如果您要比较 int,您可以创建一个比较来比较它们与第三个点 P 的距离,该点将是函子实例的成员。
函子通常不太容易阅读(对于不熟悉 C++ 的人来说)。
请注意,您不需要继承
binary_operator
即可使其工作,尽管它确实为您提供了一些不错的typedef
。They should all be the same in terms of performance, but there are other differences between them:
The first two save you having to explicitly specify the comparator, and can be used easily with other operations, possibly poorly defined ones that don't allow explicit specification of a comparator.
Only the functor allows additional data for the comparison. For example, if you were comparing
int
s, you could create a comparison that compares their distance from a third point, P, which would be a member of the functor instance.Functors are generally less easy to read (to those not familiar with C++).
Note, you don't need to inherit
binary_operator
for it to work, although it does give you some nicetypedef
s.对于大多数目的,a.和b。是一样的。所以真正的问题是,何时使用 a/b,何时使用 c。
答案是:如果“小于”对于您的对象明确有意义,则使用 a 或 b。如果您的类别是数字,请使用
<
。如果“小于”在您的类上下文中没有意义,那么请不要重载“operator<”为你的班级。它会让用户感到困惑。使用c。相反,要么将其设置为嵌套类,要么在类中对其进行 typedef,这样您就可以将其编写为
Widget::Compare
。For most purposes, a. and b. are the same. So the real question is, when to use a/b and when to use c.
The answer is: use a or b if "less than" makes sense for your object in unequivocal terms. If your class is a number, use
<
.If "less than" makes no sense in the context of your class, then please don't overload "operator<" for your class. It will confuse users. Use c. instead, and either make it a nested class or typedef it inside your class so you can write it as
Widget::Compare
.