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)