一、背景引入
正如所有了解零件(Widget)的人所知道的,Widget有重量和最高速度
class Widget {
public:...
size_t weight() const;
size_t maxSpeed() const;
...
};
此外众所周知的是给Widget排序的自然方法是按重量。
用于Widget的operator<表现成这样:
bool operator<(const Widget& lhs, const Widget& rhs){
return lhs.weight() < rhs.weight();
}
二、问题拓展
但是假设我们想建立一个按照最高速度排序Widget的multiset<Widget>。我们知道multiset<Widget>的默认比较函数是less<Widget>,而且我们知道默认的less<Widget>通过调用Widget的operator<来工作。鉴于这种情况,好像得到以最高速度排序的multiset<Widget>很明显一种方法是通过特化less<Widget>来切断less<Widget>和
operator<之间的纽带,让它只关注Widget的最高速度:
// 这是一个std::less的Widget的特化;也是非常坏的主意
template<>
struct std::less<Widget>: public td::binary_function<Widget,Widget, bool> {
bool operator()(const Widget& lhs, const Widget& rhs) const {
return lhs.maxSpeed() < rhs.maxSpeed();
}
};
特别是当没有理由时。在STL中没有一个用到less的地方你不能指定一个不同的比较类型。回到我们原先以最高速度排序的multiset<Widget>的例子,我们要得到希望的结果所需的所有事情就是建立一个叫做除了less以外的几乎任何名字的仿函数类来对我们感兴趣的东西进行比较。
嗨,这里有一个例子:
struct MaxSpeedCompare: public binary_function <Widget, Widget, bool> {
bool operator()(const Widget& lhs, const Widget& rhs) const {
return lhs.maxSpeed() < rhs.maxSpeed();
}
};
要创造我们的multiset,我们使用MaxSpeedCompare作为比较类型,因此避免了默认比较类型的使用(当然也就是less<Widget>):
multiset<Widget, MaxSpeedCompare> widgets;
这条代码确切地说出了它的意思。它建立了一个Widget的multiset,按照仿函数类MaxSpeedCompare所定义方法排序。
对比这个:
multiset<Widget> widgets;
这个表示widgets是一个以默认方式排序的Widget的multiset。在技术上,那表示它使用了less<Widget>,但是实际上每人都要假设那真的意味着它是按operator<来排序。
不要通过把less的定义当儿戏来误导那些程序员。如果你使用less(明确或者隐含),保证它表示operator<。如果你想要使用一些其他标准排序对象,建立一个特殊的不叫做less的仿函数类。它真的很简单。