0

Is it allowed by the standard for a deque to allocate is memory in a sparse way?

My understanding is that most implementations of deque allocate memory internally in blocks of some size. I believe, although I don't know this for a fact, that implementations allocate at least enough blocks to store all the items for there current size. So if a block is 100 items and you do

std::deque<int> foo;
foo.resize( 1010 );

You will get at least 11 blocks allocated. However given that in the above all 1010 int are default constructed do you really need to allocate the blocks at the time of the resize call? Could you instead allocate a given block only when someone actually inserts an item in some way. For instance the implementation could mark a block as "all default constructed" and not allocate it until someone uses it.

I ask as I have a situation where I potentially want a deque with a very large size that might be quite sparse in terms of which elements I end up using. Obviously I could use other data structures like a map but I'm interested in what the rules are for deque.

A related question given the signature of resize void resize ( size_type sz, T c = T() ); is whether the standard requires that the default constructor is called exactly sz times? If the answer is yes then I guess you can't do a sparse allocation at least for types that have a non trivial default constructor, although presumably it may still be possible for built in types like int or double.

4

3 回答 3

3

中的所有元素都deque必须正确构造。如果你需要一个稀疏的实现,我会建议一个deque(或一个vector)指向指针或一个Maybe类(你真的应该在你的工具箱中有一个),它在类型有效之前不会构造类型。这不是 的作用deque

于 2012-07-10T11:32:25.103 回答
3

23.3.3.3deque::resize将附加sz - size()默认插入元素的状态(sz是 的第一个参数deque::resize)。

默认插入(参见 参考资料23.2.1/13)意味着元素由表达式初始化allocator_traits<Allocator>::construct(m, p)(​​其中m是分配器和p要构造的类型的指针)。所以内存必须可用,并且元素将被默认构造(初始化?)。

总而言之:deque::resize如果要符合要求,就不能懒惰地构造对象。您可以通过将其包装在一个boost::optional或任何其他Maybe容器中来轻松地将惰性构造添加到一个类型中。

于 2012-07-10T11:41:06.590 回答
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元素。

于 2012-07-10T11:39:16.483 回答