为什么 libc++ 中的 std::array<T,0> 的大小和对齐方式是 T?

Why is std::array<T,0> sized and aligned according to T in libc++?

提问人:Daniel Langr 提问时间:5/11/2023 最后编辑:ks1322Daniel Langr 更新时间:5/11/2023 访问量:385

问:

在 libc++ 中,专用化有一个成员 () 数组,该数组根据 (source) 对齐和调整大小。我想知道这种实现的原因是什么,因为这个成员()似乎没有在任何地方使用。为了进行比较,libstdc++ 使用空成员,而 Microsoft STL 使用空成员(如果不可默认构造)(否则,它将创建单元素数组)。std::array<T,0>constcharT__elems_T

差异的现场演示:https://godbolt.org/z/1o167na6z

C libc++ 标准阵列

评论

2赞 Alan Birtles 5/11/2023
@AyxanHaqverdili使通用编程变得简单
1赞 Aykhan Hagverdili 5/11/2023
@AlanBirtles 我不相信允许实例化一个实际上一无所获的泛型函数是有益的。
4赞 BoP 5/11/2023
@Ayxan - 它使免于专注于 0 号。只需遍历数组元素,它就可以工作了。允许的原因相同 - 它返回指向任何元素的指针。new int[0]
5赞 Alan Birtles 5/11/2023
@AyxanHaqverdili在我的脑海中,一个用例可能是具有固定大小缓存的结构,拥有大小为 0 的缓存将是完全有效的
5赞 Daniel Langr 5/11/2023
@AyxanHaqverdili 另一个示例可能是以递归方式实例化的模板,其基本情况涉及 0。

答:

10赞 Alan Birtles 5/11/2023 #1

std::array 允许大小为零,但基础 C 数组的大小不能为零。因此,实现将需要一些特殊情况来处理此问题。

该标准没有指定这种实现必须是什么,也没有真正对行为、调用或未定义的行为施加许多约束。有一个约束条件是 .由于约束不多,因此您期望不同的实现对它使用不同的解决方法。front()back()array.begin() == array.end()

Libc++ 最初使用单元素数组,但这不适用于非默认的可构造类型。为了保持 ABI 兼容性,它被替换为相同大小的阵列。char

评论

0赞 Daniel Langr 5/11/2023
我同意,但是如果没有理由这样做,实现通常会尝试尽可能高效。
0赞 Passer By 5/11/2023
@DanielLangr “高效”是什么意思?
2赞 Daniel Langr 5/11/2023
@PasserBy 单个分配的字节比字节(具有额外的可能填充)效率更高(内存)。sizeof(T)
0赞 Daniel Langr 5/11/2023
谢谢,更新似乎包括答案,即 ABI 兼容性。
0赞 Daniel Langr 5/11/2023
@AyxanHaqverdili 是的,使用 MSVC,此代码确实打印在控制台上:.Xstruct X{ X() { std::cout << "X"; } }; int main() { std::array<X, 0> a; }