boost的operators库解决了用最少的操作符重载来完成最多的操作符实现。例如使用<操作符即可完成>= <= >操作,使用==操作符即可实现!=操作,由此如果要实现很多操作,则需要一个多继承来实现所有的操作符,但是我们大家都知道,在c++里使用多继承是很不好的编程习惯,如果能避免多继承是最好的,那怎么将多继承,自动转换为单继承呢?operators库真的是很变态啊,下面咱们来看boost的operators库中的源码一探究竟:
template <typename T> class empty_base {
//empty_base的实现,一个空的继承类,里面放置了一个dummpy
// Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
#if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
bool dummy;
#endif
};
//class B的默认值即为empty_base<T>
template <class T, class B = ::boost::detail::empty_base<T> >
struct less_than_comparable1 : B
{
friend bool operator>(const T& x, const T& y) { return y < x; }
friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
};
也就是通过这种链式的关系,可以将本来是多继承的关系,通过链式展开成继承关系,这个跟loki库中的GenLinearClass很类似。通过编译器对继承关系的解析来完成一系列的继承操作,从而把整个类展开。如下所示
class Point3D : public less_than_comparable1<Point, equality_comparable1<Point>>
{
int x,y,z;
}
这样通过这种写法就将多继承轻松的转换成了单继承操作,真的是非常牛逼啊!
核心机制:
1.采用继承的方式
2.将需要特化的属性由模板传入
3.把每个功能划分到每个模板组件中去,在这里体现的就是将小于操作、等于操作分别划分到各个模板类中,需要的时候通过基类链将其连接派生过来。