std :: dynarray与std :: vector


84

C ++ 14提出了std::dynarray

std :: dynarray是一个序列容器,该容器封装大小固定在构造上的数组,并且在对象的整个生命周期中都不会改变。

std::dynarray必须与一样在运行时分配std::vector

那么,std::dynarray可以使用的std::vector动态性更好(同时又可调整大小)的好处和用法是什么?


1
嘿,因为“ C ++ 14”何时是标记?前几天我一直在寻找它,但它并不存在……
Kerrek SB 2013年

1
std::valarray重命名为std::dynarraystd::dynarray无法调整尺寸时动态如何?
yasouser

9
@yasouser,不,与无关valarray。它是动态的,因为数组的长度是运行时值,不需要在编译时就知道,这与std::array
Jonathan Wakely 2013年

21
请注意,在上周的C ++标准委员会会议上,dynarray它已从C ++ 14中删除,并放入了将来的技术规范中(认为它是TR1的新版本),因为它存在一些严重的技术问题。
皮特·贝克尔

2
dynarray不再是C ++ 14草案的一部分
cassinaj,2015年

Answers:


89

那么std::dynarray,当我们可以使用std::vector哪个更动态(可调整大小)时,的好处和用法是什么?

dynarrayvector,它更小,更简单,因为它不需要管理单独的大小和容量值,也不需要存储分配器。

但是,主要的性能优势是来自以下事实:鼓励实现dynarray在可能的情况下在堆栈上进行分配,从而避免了任何堆分配。例如

std::dynarray<int> d(5);   // can use stack memory for elements
auto p = new std::dynarray<int>(6);  // must use heap memory for elements

这种优化需要编译器的配合,不能将其实现为纯库类型,并且尚未实现必要的编译器魔术,而且没人知道这样做的难易程度。由于缺乏实施经验,在上周于芝加哥举行的C ++委员会会议上,决定退出std::dynarrayC ++ 14,并发布单独的数组扩展TS(技术规范)文档定义std::experimental::dynarray和运行时绑定的数组(ARB,类似到C99 VLA。)这std::dynarray几乎可以肯定不在C ++ 14中。


1
太好了,我想知道在野外是否有任何非平凡的实现dynarray。我一直认为,在某些东西可以标准化之前,您需要对现有实践进行两个独立的实现。
Kerrek SB 2013年

不,没有stack-allocating的已知实现dynarray。尽管实施经验非常有用,但是并没有固定的要求(但有人会说应该存在!)
Jonathan Wakely 2013年

只是在这里进行头脑风暴,但是如何创建两个函数:std :: dynarray make_dyn_autostorage(int)和std :: dynarray make_dyn_heap(int)?
2013年

2
@KerrekSB,是的,芝加哥的第10个库议案是:“移动我们为计划的阵列扩展TS创建工作文件,删除两篇论文N3639对C ++ 14 CD所做的编辑,“具有自动运行时大小的数组“存储期限(修订5)” ,“ N3662,“ C ++动态数组(dynarray)””,并指导Array Extensions TS项目编辑器将这些词语作为其初始内容应用于Array Extensions工作文件。
Jonathan Wakely

3
@ h9uest与“ C ++专家”无关,这些是ISO技术委员会可交付成果的正式名称,请参见iso.org/iso/home/standards_development/…iso.org/iso/home/standards_development /…
Jonathan Wakely 2015年

31

就像您自己说的,它std::dynarray是用于固定大小的动态数组。它不可调整大小。它大致在讲的改善new T[N]及以上std::unique_ptr<T[]>(new T[N])

无需调整大小或管理容量,意味着您可以以更少的复杂性和更少的空间来实现数据结构。

此外,它std::dynarray是一种怪异的动物,它允许实现以不同的非特定方式实现它,例如,可以将数组放在堆栈上。调用分配函数是“可选的”。您可以指定分配器来构造数组的元素,但这不是该类型的一部分。

你可能也想知道为什么我们需要std::dynarray 变长数组。C ++ 14中的VLA更具限制性。它们只能是局部的自动变量,无法指定分配策略,当然它们也没有标准的容器接口。


来自23.3.4.2的“当前草稿”(例如Google缓存)的一些示例:

explicit dynarray(size_type c);

效果:分配c元素的存储。可能会或可能不会调用global operator new

template <class Alloc>
dynarray(size_type c, const Alloc& alloc);

效果:等效于前面的构造函数,除了每个元素都是使用Uses-allocator构造的

是否可以使用给定的分配器构造数组元素是一个全局特征:

模板结构use_allocator,Alloc>:true_type {};

要求: Alloc应为分配者(17.6.3.5)。[注意:此特征的专业性会通知其他dynarray可以使用分配器构造的库组件,即使它没有嵌套的allocator_type。

编辑:乔纳森·韦克利(Jonathan Wakely)的答案注定要更具权威性和洞察力。


将分配器传递给dynarray的构造函数永远不会用于分配,它仅用作元素的构造函数的参数(使用“ uses-allocator构造”)。这就是为什么您无法查询是否使用了分配器的原因:因为它从未使用过。
Jonathan Wakely

@JonathanWakely:啊,我误会了。谢谢,固定!
Kerrek SB 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.