标准定义的 std::array 的大小 [英] Is the size of std::array defined by standard

查看:28
本文介绍了标准定义的 std::array 的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C++11 中,std::array 被定义为具有不比数组差的连续存储和性能,但我无法确定标准的各种要求是否意味着std::array 具有与普通数组相同的大小和内存布局.也就是说,您可以依靠 sizeof(std::array) == sizeof(int)*N 还是特定于实现?

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

std::vector>x(M);typedef (*ArrayPointer)[N];ArrayPointer y = (ArrayPointer) &x[0][0];//像普通的多维数组一样使用 y

它适用于我尝试过的两个编译器(GNU 和英特尔).此外,我能找到的所有 3rd 方文档(像这样)都指出 std::array 只是与普通数组一样有效的内存,结合连续要求意味着它必须具有相同的内存布局.但是我在标准中找不到这个要求.

解决方案

几乎需要.具体来说,第 23.3.2.1/2 节说:

<块引用>

数组是一个聚合(8.5.1),可以用语法初始化

arraya = { 初始化列表};

<块引用>

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

由于它是一个聚合,它不能使用任何类型的构造函数将初始化列表中的数据转换为正确的格式.那真的只剩下一种可能性:它唯一可以存储的东西就是值本身.

我想 std::array 可以在指定数据之后存储某种辅助数据,例如设置为某个预定义值的额外内存,所以如果你写到数组的末尾,你可能会改变那个数据.然后编译器/运行时会在关闭时检查这些值,如果您更改了这些值,请报告您的代码的未定义行为.

也有可能编译器可以std::array 做不同的填充/对齐而不是内置数组.一个明显的例子是支持超级对齐要求,例如与英特尔的 SSE 指令一起使用的数据.内置数组不能支持超对齐,但我认为std::array的规范可能勉强够宽松允许.

底线:不考虑可能存在多少可能性的问题,很明显std::array 不一定要遵循您所询问的规则.

In C++11 std::array is defined to have contiguous storage and performance that is no worse than an array, but I can't decide if the various requirements of the standard imply that std::array has the same size and memory layout as a normal array. That is can you count on sizeof(std::array<int,N>) == sizeof(int)*N or is that implementation specific?

In particular, is this guaranteed to work the way you would expect it to:

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

It works in the two compilers I tried (GNU & Intel). Furthermore, all the 3rd party documentation I could find (like this), states that std::array is just as memory efficient as a plain array, which combined with the contiguous requirement would imply that it must have identical memory layout. However I can't find this requirement in the standard.

解决方案

It's nearly required. Specifically, §23.3.2.1/2 says:

An array is an aggregate (8.5.1) that can be initialized with the syntax

array<T, N> a = { initializer-list };

where initializer-list is a comma-separated list of up to N elements whose types are convertible to T.

Since it's an aggregate, it can't use any sort of constructor to convert the data in the initializer-list to the correct format. That really only leaves one possibility: about the only thing it can store are the values themselves.

I suppose it would be possible for an std::array to store some sort of auxiliary data following the specified data, such as extra memory set to some predefined value, so if you write past the end of the array, you'd probably change that data. The compiler/run-time would then check those values at shut-down, and if you'd changed the values, report your code's undefined behavior.

It's also possible that a compiler could do padding/alignment differently for an std::array than for a built-in array. One obvious example for which this could even be desirable would be to support super-alignment requirements, such as data for use with Intel's SSE instructions. A built-in array can't support super-alignment, but I think the specification of std::array might be barely loose enough to allow it.

Bottom line: without getting into questions of how many possibilities might exist, it's pretty clear that std::array doesn't necessarily have to follow the rule you're asking about.

这篇关于标准定义的 std::array 的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆