4.8.8 高级议题
本节讨论关于operators库的一些高级议题。
二元操作符
二元操作符(如-、+)的两个参数一般是同类型的,但有时候也可能会是不同类型的。比如point,可以允许它与一个整型的标量做加减法,其效果是每个坐标值对标量做加减法。
operators库提供了使用两个模板类型参数的概念类,用来支持这种用法,例如less_than_comparable < T, U>。对于不支持模板偏特化的编译器,operators为每个操作符提供额外的两种形式,增加后缀"1"和"2"。如果程序可能在不同的编译器上编译,为了兼容请使用带后缀的模板。例如:
- class point:
- boost::totally_ordered<point,
- boost::addable1<point> , //一个模板参数的概念类
- boost::addable2<point, int> > //两个模板参数的概念类
- {
- public:
- ...
- point& operator+=(const int& r)
- {
- x += r;
- y += r;
- z += r;
- return *this;
- }
operators复合运算概念
operators库里有一个特别的复合运算概念:operators,它提供了所有数学操作符的重载,包括比较运算、算术运算、位运算和步进运算。但建议读者最好不要用它,它是历史遗留产物,其模板声明中没有Base类,不能被用于基类链与其他概念组合。而且operators库没有对它的改进打算。
其他操作符重载
除了基本的算术操作符、比较操作符和解引用操作符,operators库还实现了更多的操作符,包括许多复杂的复合运算概念,还有迭代器操作符和一些辅助模板类。
限于篇幅本书不对它们进行详细解释,但如果读者理解了operators库的基本原理和用法,掌握它们不会是一件困难的事情。
更多的例子
operators库非常实用,本书在以下的章节也用到了它来简化操作符重载定义,读者可进一步参考:
5.1.4节(第166页)"应用于自己的类",依据operator的设计原理,实现了流操作符的重载;
7.1.6节(第243页)"实现ref_array"和附录,有operators的更详细的使用例子。
9.2.10节(第348页)"实现无限精度的整数类型",实现了一个具有无限精度整数类iint,用到了totally_ordered和addable。