C ++标准对sizeof(std::array<char, N>)
应该是什么(对于某些常量N
)说了什么?
在comment to a different question中,有人提到std::array
并不总是“堆栈分配”。该评论是对一个不同的评论的回应,该评论推测为std::array
设置一个太大的常量被声明为局部变量可能导致程序因“资源分配”变量的资源不足而中止。我假设后续评论意味着std::array
可以以某种方式切换到动态分配模式。
我可以想象可能会有某种SFINAE应用于数组大小阈值,触发std::array
的特化,实际上动态分配数组并对其进行管理。在这种情况下,sizeof(std::array<...>)
可能只是指针的大小。这是允许发生的吗?
答案 0 :(得分:13)
显然sizeof(std::array<char, N>) != N
如果N == 0
。它也不一定适用于N > 0
。
§23.3.2.1[array.overview] / p1-2:
标题
<array>
定义了用于存储固定大小的类模板 对象序列。数组支持随机访问迭代器。一个array<T, N>
的实例存储N
类型的T
元素,以便这样做size() == N
是一个不变量。存储数组的元素 连续地,意味着如果a
是array<T, N>
,那么它就会服从 所有&a[n] == &a[0] + n
的身份0 <= n < N
。数组是一个 可以使用语法
初始化的聚合(8.5.1)array<T, N> a = { initializer-list };
其中
initializer-list
是以逗号分隔的列表,最多为N
类型可转换为T
的元素。
§8.5.1[dcl.init.aggr] / p1:
聚合是一个没有用户提供的数组或类(第9条) 构造函数(12.1),没有私有或受保护的非静态数据成员 (第11条),没有基类(第10条),也没有虚函数 (10.3)。
由于array
是聚合类型,因此它不能具有执行动态分配的自定义构造函数,并且必须直接存储元素,因为它必须能够使用聚合初始化从初始化列表初始化。但是,标准中没有任何内容阻止实现在其C样式数组成员之后添加额外的东西,只要{em>初始化列表最多包含array<T, N> a = { initializer-list };
时N
具有已定义的语义{{} 1}}成员。一个看起来像
template<typename T, size_t N>
struct array {
//typedefs and member functions omitted
T _Elems[N];
double _Because_I_can;
};
// specialization for N == 0 case omitted
完全合法。因此,无法保证sizeof(std::array<char, N>) == N
。