4.8.7 下标操作符
operators库使用indexable提供了下标操作符[]的支持,它也属于解引用的范畴,用法与dereferenceable很相似,类摘要如下:
- template <class T, class I, class R, class B >
- struct indexable : B
- {
- R operator[](I n) const;
- };
indexable模板参数列表中的T和B含义与dereferenceable的T和B含义相同,分别是子类类型和基类链的父类类型。
参数I是下标操作符的值类型,通常应该是整数,但也可以是其他类型,只要它能够与类型T做加法操作。参数R是operator[]的返回值类型,通常应该是一个类型的引用。
indexable要求子类提供一个operator+(T, I)的操作定义,类似于一个指针的算术运算,它应该返回一个迭代器类型,能够使用operator*解引用得到R类型的值。
与dereferenceable的例子类似,我们使用一个my_smart_array类来模仿实现scoped_array。my_smart_array从indexable公开继承,下标操作符类型是int,operator[]的返回值类型是T&:
- template<typename T>
- class my_smart_array:
- public indexable<my_smart_array<T>, int, T& >
- {
- T *p; //保存动态数组指针
- public:
- typedef my_smart_array<T> this_type;
- typedef T* iter_type; //迭代器类型
- my_smart_array(T *x):p(x){} //构造函数
- ~my_smart_array(){delete[] p;} //析构函数
- friend iter_type operator+(const this_type& a, int n)
- {
- return a.p + n; //返回一个迭代器,可以使用operator*操作
- }
- };
由于my_smart_array实现了operator+,因此它支持算术运算,又由于它继承自indexable,所以它还自动获得了operator[]的定义:- my_smart_array<double> ma(new double[10]);
- ma[0] = 1.0; //operator[]
- *(ma + 1) = 2.0; //指针算术运算
- cout << ma[1] << endl; //输出2.0