设为首页 加入收藏

TOP

4.8.2 算术操作符的用法
2013-10-07 15:01:38 来源: 作者: 【 】 浏览:67
Tags:4.8.2 算术 操作 符的 用法

4.8.2  算术操作符的用法

我们使用之前4.5.3节定义的三维空间的点point作为opreators库的示范类,在此把它重新定义如下(去掉了swap函数):

  1. class point  
  2. {  
  3.     int x, y, z;  
  4. public:  
  5.     explicit point(int a=0, int b=0, int c=0):x(a),y(b),z(c){}  
  6.     void print()const  
  7.     {   cout << x <<","<< y <<","<< z << endl;  }  
  8. };  

我们先来实现less_than_comparable,它要求point类提供<操作符,并由它继承。假定point的小于关系是三个坐标值的平方和决定的,下面的代码示范了less_than_comparable的用法,只需要为point增加父类,并定义less_than_comparable概念所要求的operator<:
  1. #include <boost/operators.hpp> 
  2. class point:  
  3.     boost::less_than_comparable<point>              //小于关系,私有继承  
  4. {  
  5. public:  
  6.     friend bool operator<(const point& l, const point& r)  
  7.     {  
  8.         return (l.x*l.x + l.y*l.y +l.z*l.z < 
  9.                 r.x*r.x + r.y*r.y +r.z*r.z);  
  10.     }  
  11. ...                                             //其他成员函数  
  12. };  

less_than_comparable作为基类的用法可能稍微有点奇怪,它把子类point作为了父类的模板参数:less_than_comparable,看起来好像是个"循环继承"。实际上,point类作为less_than_comparable的模板类型参数,只是用来实现内部的比较操作符,用作操作符函数的类型,没有任何继承关系。less_than_comparable生成的代码可以理解成这样 :
  1. //template<TT = point> 
  2. struct less_than_comparable  
  3. {  
  4.      friend bool operator>=(const point& x, const point& y)  
  5.      { return !(x < y); }  
  6. }  

明白了less_than_comparable的继承用法,剩下的就很简单了:point类定义了一个友元operator<操作符,然后其余的>、<=、>=就由less_than_comparable自动生成。几乎不费什么力气,在没有污染名字空间的情况下我们就获得了四个操作符的能力:
  1. int main()  
  2. {  
  3.     point p0, p1(1,2,3), p2(3,0,5), p3(3,2,1);  
  4.  
  5.     assert(p0 < p1 && p1 < p2);  
  6.     assert(p2 > p0);  
  7.     assert(p1 <= p3);  
  8.     assert(!(p1<p3)&&!(p1>p3) );  
  9. }  

同样我们可以定义相等关系,使用equality_comparable,规则是point的三个坐标值完全相等,需要自行实现operator==:
  1. class point:boost::less_than_comparable<point>  //使用多重继承  
  2.     ,boost::equality_comparable<point>              //新增相等关系  
  3. {  
  4. public:  
  5.     friend bool operator<(const point& l, const point& r)  
  6.     {   /*同前*/      }  
  7.     friend bool operator==(const point& l, const point& r)  
  8.     {   return r.x == l.x && r.y == l.y && r.z == l.z;  }  
  9. };  

然后我们就自动获得了operator!=的定义:
  1. point p0, p1(1,2,3), p2(p1), p3(3,2,1);  
  2. assert(p1 == p2);  
  3. assert(p1 != p3);  

在使用operators库时要注意一点,模板类型参数必须是子类自身,特别是当子类本身也是个模板类的时候,不要错写成子类的模板参数或者子类不带模板参数的名称,否则会造成编译错误。假如我们改写point类为一个模板类:
  1. template<typename T> class point {...} 

那么如下的形式都是错误的:
  1. template<typename T> class point:boost::less_than_comparable<T> 
  2. template<typename T> class point:boost::less_than_comparable<point> 

正确的写法应该是:
  1. template<typename T> class point:boost::less_than_comparable< point<T> > 

因为只有point才是模板类point的全名。
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇4.7.5 与optional 的区别 下一篇4.8.6 解引用操作符

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: