基于C++标准:std::array<std::byte/unsigned char>能否隐式创对象并提供存储?
问题1:创建std::array<std::byte>或std::array<unsigned char>时,是否会隐式创建对象?
根据[intro.object#16]的规定:
除常量求值期间外,启动unsigned char数组或std::byte数组生命周期的操作会在该数组占据的存储区域内隐式创建对象。
[注5:数组对象为这些对象提供存储。——结束注]
除常量求值期间外,任何对operator new或operator new[]的隐式/显式调用都会在返回的存储区域内隐式创建对象,并返回指向合适对象的指针。
std::array<T, N>是聚合类型,其内部存储的T序列满足连续有效范围的要求(由data()成员保证)。只要不在常量求值语境下,创建std::array<std::byte, N>或std::array<unsigned char, N>时,其内部连续序列的生命周期启动操作,会触发存储区域内的隐式对象创建。
问题2:此类std::array是否能够为其他对象提供存储(符合[intro.object#3]的定义)?
[intro.object#3]对数组为新对象提供存储的条件定义如下:
如果在类型为“N个unsigned char的数组”或“N个std::byte的数组”的对象e关联的存储中创建完整对象,当满足以下条件时,该数组为新对象提供存储:
- e的生命周期已开始且未结束;
- 新对象的存储完全容纳在e内;
- e中无嵌套满足约束的数组对象。
对于std::array<std::byte, N>或std::array<unsigned char, N>:
- 只要该
std::array对象处于活跃生命周期内,第一个条件满足; - 新对象的存储大小不超过
std::array的总存储容量(N * sizeof(T))时,第二个条件满足; - 基础的
std::array<T,N>内部不存在嵌套的符合约束的数组对象,第三个条件满足。
因此这类std::array完全符合[intro.object#3]的定义,可以为其他对象提供存储。
问题3:C++标准未强制要求std::array内部使用普通数组实现,但data()成员保证指针算术有效,这是否足够支持上述特性?
[sequences#array]对data()的要求为:
data()成员返回一个指针,使得[data(), data() + size())是有效范围。
标准对std::array的核心约束是元素的连续性和可通过指针算术访问,而非具体实现方式。data()保证了返回的指针可以通过算术操作遍历所有元素,意味着其存储区域是连续无间隙的。
而[intro.object#16]和[intro.object#3]的核心依赖是连续的unsigned char/std::byte存储区域及其生命周期状态。std::array通过data()满足连续存储的行为要求,无论内部是否用普通数组实现,都能支持隐式创建对象和为其他对象提供存储的特性——标准只关注行为正确性,不绑定具体实现。
内容的提问来源于stack exchange,提问作者Oersted

