为什么 STL 在 std::array 和 std::initializer_list 之间做了(另一个)区分

Why did STL made a(nother) distinction between a std::array and a std::initializer_list

为什么在编译时定义一个list,性能最好的不止一种?

基准很明确,constexpr std::initializer_list 更快,使用 甚至 更少的内存,并且 IO 读取比 constexpr std::array 少得惊人:

https://build-bench.com/b/1EDAcFjJ6NACk4Pg4tG2nbsEx0A

那么他们为什么不实现数组订阅方法 std::initializer_list 使 std::array 变得不必要。

这个问题暴露了对这里发生的事情的一些误解。

std::array 是一个数组对象。它是一个对象,其存储大小是其数组元素的存储空间。 std::initializer_list 是指向数组(由编译器创建)的 指针 。例如,您可以堆分配 std::array;你不能堆分配 std::initializer_list。好吧,你可以,但你只是在堆上分配一个指针,这通常没有帮助。这个:

auto *p = new std::initializer_list<int>{1, 2, 3, 4};

是损坏的代码,因为它堆分配了一个指向编译器创建的 临时 数组的指针。在此语句结束时立即销毁的临时数组。所以你现在有一个指向不存在的数组的指针,所以使用 *pp[x] 是未定义的行为。

std::array 做同样的事情很好,因为 array 是一个数组 .

此外,std::initializer_list的目的是而不是“在编译时定义一个列表”。顾名思义,类型的要点是为了初始化一个对象而创建一个列表。这就是为什么只能通过一段特定的 C++ 语法来提供其数据的最终来源,这种语法专门用于初始化对象:braced-init-list。

您可以使用 std::initializer_list 作为一种为某些目的创建值数组的快捷方式。但这不是类型的重点。这就是为什么它没有 operator[];因为可以从一系列值初始化的函数往往不需要该特定操作。他们通常只需要从头走到尾就可以了。