提供一组完整的比较操作符
●
提供一组完整的算术操作符
●
提供一组完整的迭代器操作符
允许你只定义所需的比较或算术操作符的一个子集,然后基于你提供的操作符自动定义其它的操作符
例如:
依照operator<来实现operator>,operator<=, and operator>=操作
其他的操作符实现类似。
注:左边为用户实现的,右边是自动实现的。
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技巧。
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>>
差距:基类链通过模板组成了一连串的单继承链表,而不是多个父类的多重继承。(将>后移)例如:set 仅依赖于概念 LessThanComparable
相等:调用operator==来判断否匹配。例如 find在set中定位,调用operator==
等价:调用operator<。例如向关联容器插入元素,调用operator<
总结:equality_comparable:基于==
equivalent: 基于<
关联容器set,map和排序算法使用:等价<,
各种查找算法find使用 :相等==