是标准定义的std :: array的大小

pav*_*von 36 c++ stl language-lawyer c++11

在C++ 11 std::array中定义的连续存储和性能并不比数组差,但我不能确定标准的各种要求是否意味着std :: array具有与普通数据相同的大小和内存布局阵列.那是你可以指望的sizeof(std::array<int,N>) == sizeof(int)*N还是具体的实施?

特别是,这保证按照您期望的方式工作:

std::vector< std::array<int, N> > x(M);
typedef (*ArrayPointer)[N];
ArrayPointer y = (ArrayPointer) &x[0][0];
// use y like normal multidimensional array
Run Code Online (Sandbox Code Playgroud)

它适用于我尝试过的两个编译器(GNU和Intel).此外,我能找到的所有第三方文档(如下所示)都表明std :: array与普通数组一样具有内存效率,它与连续需求相结合意味着它必须具有相同的内存布局.但是我在标准中找不到这个要求.

Jer*_*fin 27

几乎是必需的.具体而言,§23.3.2.1/ 2说:

数组是可以使用语法初始化的聚合(8.5.1)

array<T, N> a = { initializer-list };
Run Code Online (Sandbox Code Playgroud)

其中initializer-list是最多N个元素的逗号分隔列表,其类型可转换为T.

由于它是聚合,因此无法使用任何类型的构造函数将初始化列表中的数据转换为正确的格式.这真的只留下了一种可能性:它唯一可以存储的是价值本身.

我想这是可能的std::array存储某种以下指定的数据,比如额外的内存设为某些特定值的辅助数据,所以,如果你写过去的数组的末尾,你可能会改变这种状况的数据.然后,编译器/运行时将在关闭时检查这些值,如果您更改了值,则报告代码的未定义行为.

对于内置数组而言,编译器也可以对填充/对齐进行不同的填充/对齐std::array.一个明显的例子就是支持超对齐要求,例如用于英特尔SSE指令的数据.内置数组不能支持超对齐,但我认为规范std::array可能几乎不足以允许它.

一句话:没有涉及可能存在多少种可能性的问题,很明显,std::array并不一定要遵循你所询问的规则.

  • 我认为它也可以有填充,即使在开头,因为它不需要是标准布局类(并且不能,因为它的成员可能是非标准布局类型). (2认同)