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<Widget>容器。mutliset<Widget>的默认比较函数是less<Widget>,而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<Widget, MaxSpeedCompare> datas;它创建了一个存放Widget的multiset容器,排序规则由MaxSpeedCompare定义。

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

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

42. 确保lessT与operator小于具有相同的语义相关推荐

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

    Widget类定义如下: class Widget { public:...size_t weight() const;size_t maSpeed() const;... } 通常情况下,按重量对W ...

  2. [6 函数子类及函数] 42. 确保less<T>与operator<具有相同的语义(POLA)

    假设Widget包含一个重量值和一个最大速度值: class Widget { public:...size_t weight() const;size_t maxSpeed() const;... ...

  3. Effective STL 50条有效使用STL的经验笔记

    Scott Meyers大师Effective三部曲:Effective C++.More Effective C++.Effective STL,这三本书出版已很多年,后来又出版了Effective ...

  4. 一周一论文(翻译)——[SIGMOD 19] Elasticutor:Rapid Elasticity for Realtime Stateful Stream Processing

    Abstract 弹性非常适用于流系统,以保证针对工作负载动态的低延迟,例如到达率的激增和数据分布的波动.现有系统使用以resource-centric的方法实现弹性,该方法在并行实例(即执行程序)之 ...

  5. 《C++ Primer 5th》笔记(3 / 19):字符串、向量、迭代器和数组

    文章目录 命名空间的using声明 标准库类型string 定义和初始化string对象 直接初始化和拷贝初始化 string对象上的操作 读写string对象 读取未知数量的string对象 使用g ...

  6. Effective STL 精华版读书笔记

    文章目录 容器 STL是建立在泛化之上的. vector/string 关联容器 迭代器 输入迭代器 输出迭代器 双向迭 算法 条款30:确保目标区间足够大 条款31:了解你的排序选择 条款32:如果 ...

  7. Effictive STL读书笔记

    都是一些简单的总结,可以帮助回忆当时看书的知识点~ ##第1条:慎重选择容器类型 STL容器的分类远比我想像中的多.别人意外的是stack,queue等不是STL容器,但这不是这章的重点. 你是否需要 ...

  8. C++ primer(第五版)- 1

    1. constexpr变量 C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式.声明为constexpr的变量一定是一个常量,而且必须用常量表 ...

  9. Exceptional C++ 读书笔记

    Exceptional C++ 读书笔记 1 泛型程序设计与C++标准库(没看)  Item 1 Iterator: 1)注意当前迭代器是否有效,如果无效则解引用产生程序错误: 2)注意当前迭代器生命 ...

  10. 【绝版C++书籍】《Effective STL》读书笔记

    <Effective STL>读书笔记 写在前面 0<Effective STL>中可能过时的内容 1 容器 第1条:慎重选择容器类型. 第2条:不要试图编写独立于容器类型的代 ...

最新文章

  1. CentOS 5.5 编译安装apache+php+mysql,利用CMS快速建立论坛
  2. redhat 7.3 mysql_RedHat7.3安装MySQL5.7
  3. python环境设置_CentOS 7.2环境搭建实录(第四章:python环境配置)
  4. 计算几何-经典算法-凸包
  5. linux下如何屏蔽代码,linux c 怎么屏蔽信号 使用sigprocmask命令
  6. DGL教程【二】如何通过DGL表示一个Graph
  7. SQL中Case when 方法的使用
  8. .NET Framework 4.0源代码
  9. Linux下如何同时启动多个Tomcat服务器
  10. Spring 源码分析(三) —— AOP(五)创建代理
  11. ECharts4简单入门
  12. linux 查看硬盘的uuid_ubuntu16.04 挂载新硬盘
  13. photoshop基础操作集合01
  14. sdn主要包含哪些接口_SDN个人理解
  15. 面试高并发,凉了!!(全程高能,建议收藏)
  16. 自动驾驶基础知识(二)——术语中英文对照
  17. 2022骨传导蓝牙耳机哪个最专业、目前最好的骨传导耳机
  18. csv转excel在线工具
  19. 如何从GFP确定最后申请的内存来自哪个zone?
  20. 差分隐私:原理、应用与展望(新加坡国立大学 萧小奎)

热门文章

  1. 如何手动添加或者修改海威康视摄像头IP地址的方法
  2. warning: mysql-community-libs-5.7.11-1.el7.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5
  3. 《C语言及程序设计》程序阅读——参数传递方式:传值与传地址
  4. 15K薪资轻松到手,要低调~
  5. Exchange Server 2010 LAB Part6.边缘传输服务器部署和应用
  6. shell,expect主机密钥免密码登录分发
  7. CLR寄宿(上) MSCOREE.DLL
  8. 7.微服务设计 --- 测试
  9. 17.Mac Ctags 使用
  10. 58. Attribute item() 方法