为什么 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};
是损坏的代码,因为它堆分配了一个指向编译器创建的 临时 数组的指针。在此语句结束时立即销毁的临时数组。所以你现在有一个指向不存在的数组的指针,所以使用 *p
或 p[x]
是未定义的行为。
对 std::array
做同样的事情很好,因为 array
是一个数组 .
此外,std::initializer_list
的目的是而不是“在编译时定义一个列表”。顾名思义,类型的要点是为了初始化一个对象而创建一个列表。这就是为什么只能通过一段特定的 C++ 语法来提供其数据的最终来源,这种语法专门用于初始化对象:braced-init-list。
您可以使用 std::initializer_list
作为一种为某些目的创建值数组的快捷方式。但这不是类型的重点。这就是为什么它没有 operator[]
;因为可以从一系列值初始化的函数往往不需要该特定操作。他们通常只需要从头走到尾就可以了。
为什么在编译时定义一个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};
是损坏的代码,因为它堆分配了一个指向编译器创建的 临时 数组的指针。在此语句结束时立即销毁的临时数组。所以你现在有一个指向不存在的数组的指针,所以使用 *p
或 p[x]
是未定义的行为。
对 std::array
做同样的事情很好,因为 array
是一个数组 .
此外,std::initializer_list
的目的是而不是“在编译时定义一个列表”。顾名思义,类型的要点是为了初始化一个对象而创建一个列表。这就是为什么只能通过一段特定的 C++ 语法来提供其数据的最终来源,这种语法专门用于初始化对象:braced-init-list。
您可以使用 std::initializer_list
作为一种为某些目的创建值数组的快捷方式。但这不是类型的重点。这就是为什么它没有 operator[]
;因为可以从一系列值初始化的函数往往不需要该特定操作。他们通常只需要从头走到尾就可以了。