ndex);
// 返回只读元素
const t& operator[](int index) const;
通过两次声明同一个函数,一次带const一次没有const,就提供了对const和非const array对象的支持。返回值不同很重要,条款21对此进行了说明。
现在,array模板支持构造函数,析构函数,传值,赋值,索引,你可能想到这已经是一个完整的接口了。但再看清楚一些。假如一个用户想遍历一个整数数组,打印其中的每一个元素,如下所示:
array<int> a(10, 20); // 下标上下限为:10到20
...
for (int i = a的下标下限; i <= a的下标上限; ++i)
cout << "a[" << i << "] = " << a[i] << '\n';
用户怎么得到a的下标上下限呢?答案取决于array对象的赋值操作做了些什么,即在array::operator=里做了什么。特别是,如果赋值操作可以改变array对象的上下限,就必须提供一个返回当前上下限值的成员函数,因为用户无法总能在程序的某个地方推出上下限值是多少。比如上面的例子,a是在被定义后、用于循环前的时间段里被赋值的,用户在循环语句中就无法知道a当前的上下限值。
如果array对象的上下限值在赋值时不能改变,那它在a被定义时就固定下来了,用户就可能有办法(虽然很麻烦)对其进行跟踪。这种情况下,提供一个函数返回当前上下限值是很方便,但接口就不能做到最小。
继续前面的赋值操作可以改变对象上下限的假设,上下限函数可以这样声明:
int lowbound() const;
int highbound() const;
因为这两个函数不对它们所在的对象进行任何修改操作,而且为遵循“能用const就尽量用const”的原则(见条款21),它们被声明为const成员函数。有了这两个函数,循环语句可以象下面这样写:
for (int i = a.lowbound(); i <= a.highbound(); ++i)
cout << "a[" << i << "] = " << a[i] << '\n';
当然,要使这样