Operators库/Barton-Nackmann 技巧

作用:

提供一组完整的比较操作符

●    

提供一组完整的算术操作符

●    

提供一组完整的迭代器操作符

允许你只定义所需的比较或算术操作符的一个子集,然后基于你提供的操作符自动定义其它的操作符

例如:

依照operator<来实现operator>,operator<=, and operator>=操作

   Operators库/Barton-Nackmann 技巧_第1张图片

   Operators库/Barton-Nackmann 技巧_第2张图片

其他的操作符实现类似。

注:左边为用户实现的,右边是自动实现的。

bool operator==(const T&,const T&);  ------》bool operator!=(constT&,const T&);

T operator+=(const T&);--------------------------》T operator+(const T&,const T&);

Toperator|=(const T&,const T&);-------------》T operator|(const T&,const T&);

++,--:前增实现后增

T&operator++(T&);------------------------------》T operator++(T&,int);

等价:

booloperator<(const T&,const T&);------》bool operator==(constT&,const T&);

用法

#include"boost/operators.hpp"

classsome_class : boost::equivalent<some_class> {

  int value_;

public:

  some_class(int value) : value_(value) {}

  bool less_than(const some_class& other)const {

    return value_<other.value_;

  }

};

bool operator<(const some_class& lhs, constsome_class& rhs) {

  return lhs.less_than(rhs);

}

把派生类传给基类作为模板参数。这是一种著名的技巧,被称为Barton-Nackmann技巧。

Barton-Nackmann 技巧

1,基类 equivalent接受一个要为之定义operator==的类型为模板参数。

它通过使用operator< 为该参数化类型实现泛型风格 operator==

2,然后,类 some_class想要利用 equivalent的服务,就从它派生并把自己作为模板参数传递给 equivalent 。

3,因此,结果就是为类型some_class 定义了operator==,是依照some_class 的operator<

实现的。这就是Barton-Nackmann技巧的全部内容。

避免对象膨胀         

问题:使用Operators库常常会导致从多个基类进行继承,导致潜在的对象大小膨胀。

针对多重继承的副作用的办法:

方法一:基类链

方法二:复合概念

基类链:通过模板把多继承转换为链式的单继承

每个操作符类接受一个可选的额外的模板参数,该参数来自于它的派生类。采用以下方法:一个概念类派生自另一个,后者又派生自另一个,后者又派生自 另一个…这样就不再需要多重继承了。

作用:使用基类链避免类型增大的负作用

例子:

多重继承实现:

boost::less_than_comparable<point>, 两个类

boost::equality_comparable<point>

基类链实现:

boost::less_than_comparable<point, 一个有很大模板参数列表的类

boost::equality_comparable<point>> 

差距:基类链通过模板组成了一连串的单继承链表,而不是多个父类的多重继承。(将>后移)

相等与等价的区别

要使用关联容器 ,就要求有 等价关系 ,它通过概念LessThanComparable( operator<)定义了一个严格弱序。

例如:set 仅依赖于概念 LessThanComparable

相等:调用operator==来判断否匹配。例如 find在set中定位,调用operator==

等价:调用operator<。例如向关联容器插入元素,调用operator<

总结:

equality_comparable:基于==

equivalent:    基于<

关联容器set,map和排序算法使用:等价<

各种查找算法find使用         :相等==






 

你可能感兴趣的:(Operators库/Barton-Nackmann 技巧)