现在的位置: 首页 > 综合 > 正文

自动生成关联运算符

2013年07月04日 ⁄ 综合 ⁄ 共 4275字 ⁄ 字号 评论关闭

自动生成关联运算符

自定义运算符是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&)

【上篇】
【下篇】

抱歉!评论已关闭.