15.确保“lessT“与“operator小于“具有相同的语义

Widget类定义如下:

class Widget
{
public:
    ...
    size_t weight() const;
    size_t maSpeed() const;
    ...
}

通常情况下,按重量对Widget进行排序是最自然的方式。Widget的operator < 反映了这一点。

bool operator < (const Widget& lhs, const Widget& rhs)
{
    return lhs.weight() < rhs.weight();
}

但是在某种情况下,我们需要创建一个按照最大速度进行排序的multiset容器。mutliset的默认比较函数是less,而less在默认情况下会调用operator <来完成自己的工作。

为了让multiset按照最大速度进行排序,一种显而易见的实现方式是:特化less,切断less和operator < 之间的关系,让它只考虑Widget的最大速度:

template<> 
struct std::less<Widget> : public std::binary_function<Widget, Widget, bool>
{
    bool operator () (const Widget& lhs, const Widget& rhs) const 
    {
        return lhs.maxSpeed() < rhs.maxSpeed();
    }
}

operator < 不仅仅是less的默认实现方式,它也是程序员期望less所做的事情,让less不调用operator < 而去做别的事情,这会无端违背程序员的意愿,这与"最小给人惊奇"原则完全背道而驰,应该完全避免。

在STL中,凡是使用了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):
multiset datas;它创建了一个存放Widget的multiset容器,排序规则由MaxSpeedCompare定义。

相比之下,mutliset datas;说明了datas是一个采用默认排序方式的、存放Widget对象的mutliset容器。这意味着它使用less进行排序,但事实上所有人都会假设它是通过operator <来排序的。

应该尽量避免修改less的行为,因为这样做很可能会误导其他人。如果你使用了less,无论是显示还是隐式,都需要确保它与operator <具有相同的意义。如果你希望以一种特殊的方式来排序对象,那么最好创建一个特殊的函数子类,它的名字不能是less。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值