C++11 FAQ中文版:array

时间:2022-01-24 19:33:34

array

std::array是一个支持随机访问且大小(size)固定的容器(译注:可以认为是一个紧缩版的vector吧)。它有如下特点:

  • 不预留多余空间,只分配必须空间(译注:size() == capacity())。
  • 可以使用初始化表(initializer list)的方式进行初始化。
  • 保存了自己的size信息。
  • 不支持隐式指针类型转换。

换句话说,可以认为它是一个很不错的内建数组类型。一些代码片段:

        array<int,6> a = { 1, 2, 3 };
	a[3]=4;
	int x = a[5];	 // array的默认数据元素为0,所以x的值变成0
	int* p1 = a; // 错误: std::array不能隐式地转换为指针
	int* p2 = a.data();	// 正确,data()得到指向第一个元素的指针

不过要注意:是可以定义一个长度为0的array的;但是无法从初始化表中推导出size信息:

array<int> a3 = { 1, 2, 3 };	//错误:没有size信息
	array<int,0> a0;	 // 正确: 没有任何元素
	int* p = a0.data();	 // 为定义行为,不要这样做

array非常适合在嵌入式系统(和有类似限制/性能敏感/安全关键系统等)中使用。它提供了序列型容器该有的大部分通用函数(和vector很像):

       template<class C> C::value_type sum(const C& a)
        {
                return accumulate(a.begin(),a.end(),0);
        }

        array<int,10> a10;
        array<double,1000> a1000;
        vector<int> v;
        // …
        int x1 = sum(a10);
        int x2 = sum(a1000);
        int x3 = sum(v);

但是,它是不支持由子类到基类的自动类型转换的(注意这个潜在陷阱):

        struct Apple : Fruit { /* … */ };
        struct Pear : Fruit { /* … */ };

        void nasty(array<fruit *,10>& f)
        {
                f[7] = new Pear();
        };

        array<apple ,10> apples;
        // …
        nasty(apples);  // 错误: 不能将array转换为array;

如果支持这种转换的话,apple array中就能放pear啦。

参考:

  • Standard: 23.3.1 Class template array

(翻译:interma)