deque的标准是否允许以稀疏的方式分配内存?
我的理解是deque的大多数实现都在内部以某种大小的块分配内存。我相信,虽然我不知道这个事实,但是这些实现分配了至少足够的块来存储当前大小的所有项目。因此,如果一个块是100个项目,那么
std::deque<int> foo;
foo.resize( 1010 );
您将获得至少11个分配的区块。但是鉴于在上面所有1010 int都是默认构造的,你真的需要在调整大小调用时分配块吗?你是否可以在某人实际以某种方式插入项目时分配给定的块。例如,实现可以将块标记为“所有默认构造”,并且在有人使用它之前不会分配它。
我问我有一种情况,我可能想要一个非常大的双端队列,在我最终使用的元素方面可能非常稀疏。显然我可以使用其他数据结构,比如地图,但我对deque的规则感兴趣。
给出resize void resize ( size_type sz, T c = T() );
签名的相关问题是标准是否要求默认构造函数被正确调用sz
次?如果答案是肯定的,那么我猜你至少对于具有非平凡构造函数的类型不能进行稀疏分配,尽管可能仍然可以用于内置类型,如int或double。
答案 0 :(得分:3)
必须正确构建deque
中的所有元素。如果你需要
一个稀疏的实现,我建议deque
(或vector
)
指针或Maybe
类(你真的应该在你的工具箱中有一个)
无论如何)在有效之前不会构造类型。这不是
deque
的作用。
答案 1 :(得分:3)
23.3.3.3
声明deque::resize
将附加sz - size()
默认插入元素(sz
是deque::resize
的第一个参数。)
默认插入(参见23.2.1/13
)表示元素由表达式allocator_traits<Allocator>::construct(m, p)
初始化(其中m
是分配器,p
是指向该类型的指针将被建造)。所以内存必须可用,元素将默认构造(初始化?)。
All-in-all:deque::resize
如果想要符合要求,就不能对构造对象感到懒惰。您可以通过将惰性结构包装在boost::optional
或任何其他Maybe
容器中来轻松地将其添加到类型中。
答案 2 :(得分:0)
回答你的第二个问题。有趣的是,C ++ 03和C ++ 11之间存在差异。
使用C ++ 03,您的签名
void resize ( size_type sz, T c = T() );
将默认构造参数(除非您提供另一个值),然后从这个值复制构造新成员。
在C ++ 11中,此函数已被两个重载替换
void resize(size_type sz);
void resize(size_type sz, const T& c);
其中第一个默认构造(或值初始化)sz
元素。