自动生成关联运算符

自动生成关联运算符

自定义运算符是C++的一个特色。它可以使用很多操作变得直观,符合一般的思维方式:

例如,在大多数语言中,对于int这样的内建类型(primary type)变量a,b,一个运算过程可以写成:a + b / a – 300,这与数学运算表达式完全一样。但对于非内建类型,比如Complex就不一定了。比如在Java中,它只能写成a.add(b.div(a).sub(300)),这就很难看了。而C++中可以通过自定义运算符实现与int类似的运算表达式。

运算符的实现有一个重要的原则:不改变运算符的原意。不应该把“+”号重载成减法运算,也不应把“&&”定义为乘方,虽然这些重定义在语法上合法。这一原则的一个引申概念就是有关联的运算符其间的关系不应变化。“+=”和“+”就是一对关联运算,”<”,”>”,”<=””>=”也是一组相关联的运算。其关联关系是这样的:

a = a + b 等价于 a += b

a < b,也应有 b > a, b>= a, a<=b

关联运算符应一起实现,为了保证其相关性不变,在一组关联运算符中只实现一个基本运算符,其它运算符都使用这个基本运算符实现。例如加法运算以+=为基本运算,而+调用+=运算符来实现。

class A

{

  A& operator+=(A const& a);

};

A operator+(A const& a, A const& b)

{

   A result = a;

   result += b;

   return result;

}

关系运算符更是有一套模式化的实现方法。如果A定义了“<“号,则在STL中为它定义了如下模板。

template <class _Tp>

inline bool _STLP_CALL operator>(const _Tp& __x, const _Tp& __y) {

  return __y < __x;

}

 

template <class _Tp>

inline bool _STLP_CALL operator<=(const _Tp& __x, const _Tp& __y) {

  return !(__y < __x);

}

 

template <class _Tp>

inline bool _STLP_CALL  operator>=(const _Tp& __x, const _Tp& __y) {

  return !(__x < __y);

}

它们被定义在std::rel_ops命名空间中,要使用它们,需要在类中声明using namespace std::rel_ops

这可以算是最基本的一个关联运算符生成器了,可惜它太少了一点,也不够灵活。不过在boost库中这个强大的功能被补全了,这就是boost::operators

operator主要通过继承和友元来为类型提供运算符定义。

用法1通过继承:

class A : boost:: less_than_comparable<A>

{

  friend bool operator<(A const&a, A const& b);

};

用法2通过模板友元:

class A

{

  friend bool operator<(A const&a, A const& b);

};

 

template boost:: less_than_comparable<A>; //显式实例化模板。

boost:: less_than_comparable模板类提供了以下一组友元:

friend bool operator>(const T& x, const T& y) { return y < x; }

    friend bool operator<=(const T& x, const T& y) { return !(y < x); }

    friend bool operator>=(const T& x, const T& y) { return !(x < y); }

它们都依赖于A定义的operator<运算符。

Boost不只提供只对于当前类型的运算符,还提供类型之间的运算符,如下代码。

用法1通过继承:

class A : boost:: less_than_comparable<A,B>

{

  friend bool operator<(A const&a,  B const& b);

friend bool operator>(A const&a,  B const& b);

};

用法2通过模板友元:

class A

{

  friend bool operator<(A const&a,  B const& b);

friend bool operator>(A const&a,  B const& b);

};

template boost:: less_than_comparable<A, B>; //显式实例化模板。

 

boost:: less_than_comparable<A,B>模板类提供了以下一组友元:

bool operator<=(const T&, const U&)

bool operator>=(const T&, const U&)

bool operator>(const U&, const T&)

bool operator<(const U&, const T&)

bool operator<=(const U&, const T&)

bool operator>=(const U&, const T&)

以下是一张boost提供的模板,模板提供的运算符和模板所依赖的运算符的对应表。

 

T: primary operand type U: alternate operand type t, t1: values of type T u: value of type U

模板

提供的操作符

所依赖的运算符

less_than_comparable<T>

less_than_comparable1<T>

bool operator>(const T&, const T&)
bool operator<=(const T&, const T&)
bool operator>=(const T&, const T&)

t < t1.

less_than_comparable<T, U>
less_than_comparable2<T, U>

bool operator<=(const T&, const U&)
bool operator>=(const T&, const U&)
bool operator>(const U&, const T&)
bool operator<(const U&, const T&)
bool operator<=(const U&, const T&)
bool operator>=(const U&, const T&)

t < u. t > u.

equality_comparable<T>
equality_comparable1<T>

bool operator!=(const T&, const T&)

t == t1.

equality_comparable<T, U>
equality_comparable2<T, U>

bool operator==(const U&, const T&)
bool operator!=(const U&, const T&)
bool operator!=(const T&, const U&)

t == u.

addable<T>
addable1<T>

T operator+(const T&, const T&)

T temp(t); temp += t1.
返回值类型为T.

addable<T, U>
addable2<T, U>

T operator+(const T&, const U&)
T operator+(const U&, const T& )

T temp(t); temp += u.
返回值类型为T.

subtractable<T>
subtractable1<T>

T operator-(const T&, const T&)

T temp(t); temp -= t1.

subtractable<T, U>
subtractable2<T, U>

T operator-(const T&, const U&)

T temp(t); temp -= u.

subtractable2_left<T, U>

T operator-(const U&, const T&)

T temp(u); temp -= t.

multipliable<T>
multipliable1<T>

T operator*(const T&, const T&)

T temp(t); temp *= t1.

multipliable<T, U>
multipliable2<T, U>

T operator*(const T&, const U&)
T operator*(const U&, const T&)

T temp(t); temp *= u.

dividable<T>
dividable1<T>

T operator/(const T&, const T&)

T temp(t); temp /= t1.

dividable<T, U>
dividable2<T, U>

T operator/(const T&, const U&)

T temp(t); temp /= u.

dividable2_left<T, U>

T operator/(const U&, const T&)

T temp(u); temp /= t.

modable<T>
modable1<T>

T operator%(const T&, const T&)

T temp(t); temp %= t1.

modable<T, U>
modable2<T, U>

T operator%(const T&, const U&)

T temp(t); temp %= u.

modable2_left<T, U>

T operator%(const U&, const T&)

T temp(u); temp %= t.

orable<T>
orable1<T>

T operator|(const T&, const T&)

T temp(t); temp |= t1.

orable<T, U>
orable2<T, U>

T operator|(const T&, const U&)
T operator|(const U&, const T&)

T temp(t); temp |= u.

andable<T>
andable1<T>

T operator&(const T&, const T&)

T temp(t); temp &= t1.

andable<T, U>
andable2<T, U>

T operator&(const T&, const U&)
T operator&(const U&, const T&)

T temp(t); temp &= u.

xorable<T>
xorable1<T>

T operator^(const T&, const T&)

T temp(t); temp ^= t1.

xorable<T, U>
xorable2<T, U>

T operator^(const T&, const U&)
T operator^(const U&, const T&)

T temp(t); temp ^= u.

incrementable<T>

T operator++(T&, int)

T temp(t); ++t

decrementable<T>

T operator--(T&, int)

T temp(t); --t;

left_shiftable<T>
left_shiftable1<T>

T operator<<(const T&, const T&)

T temp(t); temp <<= t1.

left_shiftable<T, U>
left_shiftable2<T, U>

T operator<<(const T&, const U&)

T temp(t); temp <<= u.

right_shiftable<T>
right_shiftable1<T>

T operator>>(const T&, const T&)

T temp(t); temp >>= t1.

right_shiftable<T, U>
right_shiftable2<T, U>

T operator>>(const T&, const U&)

T temp(t); temp >>= u.

equivalent<T>
equivalent1<T>

bool operator==(const T&, const T&)

t < t1.

equivalent<T, U>
equivalent2<T, U>

bool operator==(const T&, const U&)

t < u. t > u.

partially_ordered<T>
partially_ordered1<T>

bool operator>(const T&, const T&)
bool operator<=(const T&, const T&)
bool operator>=(const T&, const T&)

t < t1. t == t1.

partially_ordered<T, U>
partially_ordered2<T, U>

bool operator<=(const T&, const U&)
bool operator>=(const T&, const U&)
bool operator>(const U&, const T&)
bool operator<(const U&, const T&)
bool operator<=(const U&, const T&)
bool operator>=(const U&, const T&)

t < u. t > u. t == u.

 

对于同一个类要实现多组运算符,operators采用链式继承的方式,例如如果需要同时定义小于和等于符号。可以这样定义:

class A : boost:: less_than_comparable<A,  equality_comparable<A> >

{

  friend bool operator<(A const&a, A const& b);

friend bool operator==(A const&a, A const& b);

};

如果是定义类型间的小于和等于,则是这样:

class A : boost:: less_than_comparable<ABequality_comparable<AB> >

{

  friend bool operator<(A const&a,  B const& b);

friend bool operator>(A const&a,  B const& b);

friend bool operator==(A const&a,  B const& b);

};

boost预先定义了一些组合运算模板,也可以直接使用它们,例如上面的类也可以定义为:

class A : totally_ordered<T>

{

  friend bool operator<(A const&a, A const& b);

friend bool operator==(A const&a, A const& b);

};

以下是一个称为联合运算的组合运算模板的组成表:

Template

Component Operator Templates

totally_ordered<T>
totally_ordered1<T>

· less_than_comparable<T>

· equality_comparable<T>

totally_ordered<T, U>
totally_ordered2<T, U>

· less_than_comparable<T, U>

· equality_comparable<T, U>

additive<T>
additive1<T>

· addable<T>

· subtractable<T>

additive<T, U>
additive2<T, U>

· addable<T, U>

· subtractable<T, U>

multiplicative<T>
multiplicative1<T>

· multipliable<T>

· dividable<T>

multiplicative<T, U>
multiplicative2<T, U>

· multipliable<T, U>

· dividable<T, U>

integer_multiplicative<T>
integer_multiplicative1<T>

· multiplicative<T>

· modable<T>

integer_multiplicative<T, U>
integer_multiplicative2<T, U>

· multiplicative<T, U>

· modable<T, U>

arithmetic<T>
arithmetic1<T>

· additive<T>

· multiplicative<T>

arithmetic<T, U>
arithmetic2<T, U>

· additive<T, U>

· multiplicative<T, U>

integer_arithmetic<T>
integer_arithmetic1<T>

· additive<T>

· integer_multiplicative<T>

integer_arithmetic<T, U>
integer_arithmetic2<T, U>

· additive<T, U>

· integer_multiplicative<T, U>

bitwise<T>
bitwise1<T>

· xorable<T>

· andable<T>

· orable<T>

bitwise<T, U>
bitwise2<T, U>

· xorable<T, U>

· andable<T, U>

· orable<T, U>

unit_steppable<T>

· incrementable<T>

· decrementable<T>

shiftable<T>
shiftable1<T>

· left_shiftable<T>

· right_shiftable<T>

shiftable<T, U>
shiftable2<T, U>

· left_shiftable<T, U>

· right_shiftable<T, U>

ring_operators<T>
ring_operators1<T>

· additive<T>

· multipliable<T>

ring_operators<T, U>
ring_operators2<T, U>

· additive<T, U>

· subtractable2_left<T, U>

· multipliable<T, U>

ordered_ring_operators<T>
ordered_ring_operators1<T>

· ring_operators<T>

· totally_ordered<T>

ordered_ring_operators<T, U>
ordered_ring_operators2<T, U>

· ring_operators<T, U>

· totally_ordered<T, U>

field_operators<T>
field_operators1<T>

· ring_operators<T>

· dividable<T>

field_operators<T, U>
field_operators2<T, U>

· ring_operators<T, U>

· dividable<T, U>

· dividable2_left<T, U>

ordered_field_operators<T>
ordered_field_operators1<T>

· field_operators<T>

· totally_ordered<T>

ordered_field_operators<T, U>
ordered_field_operators2<T, U>

· field_operators<T, U>

· totally_ordered<T, U>

euclidian_ring_operators<T>
euclidian_ring_operators1<T>

· ring_operators<T>

· dividable<T>

· modable<T>

euclidian_ring_operators<T, U>
euclidian_ring_operators2<T, U>

· ring_operators<T, U>

· dividable<T, U>

· dividable2_left<T, U>

· modable<T, U>

· modable2_left<T, U>

ordered_euclidian_ring_operators<T>
ordered_euclidian_ring_operators1<T>

· euclidian_ring_operators<T>

· totally_ordered<T>

ordered_euclidian_ring_operators<T, U>
ordered_euclidian_ring_operators2<T, U>

· euclidian_ring_operators<T, U>

· totally_ordered<T, U>

与其它boost库一样,operators要求支持C++98标准的编译器,现在完全支持的编译器有VC7.1GCC3.3EGD 2.5以上。通过一定的方式支持GCC2.95VC6 sp3以上。

  对于完全支持的编译器,推荐使用operatorable<T>operatorable<T, U>模板。对于不完全支持的编译器,可以使用operatorable1<T>operatorable2<T,U>这两个接口。

 

阅读更多
想对作者说点什么? 我来说一句

C#经典案例 计算器

2013年12月28日 35KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭