0

両端キューがメモリをまばらに割り当てることは、標準で許可されていますか?

私の理解では、 deque のほとんどの実装は、メモリを内部的にいくつかのサイズのブロックに割り当てます。事実はわかりませんが、実装は少なくとも現在のサイズのすべてのアイテムを格納するのに十分なブロックを割り当てると思います。したがって、ブロックが 100 アイテムの場合、

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

少なくとも 11 ブロックが割り当てられます。ただし、上記のすべての 1010 int がデフォルトで構築されていることを考えると、サイズ変更の呼び出し時にブロックを割り当てる必要がありますか? 代わりに、誰かが実際に何らかの方法でアイテムを挿入したときにのみ、特定のブロックを割り当てることができますか? たとえば、実装はブロックを「すべてデフォルトで構築された」としてマークし、誰かがそれを使用するまで割り当てない可能性があります。

最終的にどの要素を使用するかという点で非常にまばらな、非常に大きなサイズの両端キューが必要になる可能性がある状況があるので、質問します。もちろん、マップのような他のデータ構造を使用することもできますが、deque のルールに興味があります。

サイズ変更の署名を考えると、関連する質問void resize ( size_type sz, T c = T() );は、標準で既定のコンストラクターが正確にsz何度も呼び出されることを要求するかどうかです。答えが「はい」の場合、少なくとも int や double などの組み込み型では可能かもしれませんが、少なくとも自明ではないデフォルト コンストラクターを持つ型に対してはスパース割り当てを行うことはできないと思います。

4

3 に答える 3

3

のすべての要素はdeque正しく構築されている必要があります。スパースな実装が必要な場合は、有効になるまで型を構成しないポインターまたはクラス(とにかくツールボックスに実際に1つあるはずです)へのdeque(または)をお勧めします。これはの役割ではありません。vectorMaybedeque

于 2012-07-10T11:32:25.103 に答える
3

23.3.3.3デフォルトで挿入された要素deque::resizeを追加する状態(は の最初の引数です)。sz - size()szdeque::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

2番目の質問に答えます。興味深いことに、C++03 と C++11 には違いがあります。

C++03 を使用して、あなたの署名

void resize ( size_type sz, T c = T() );

デフォルトでパラメータを構築し (別の値を指定しない限り)、この値から新しいメンバーをコピーして構築します。

C++11 では、この関数は 2 つのオーバーロードに置き換えられました。

void resize(size_type sz);

void resize(size_type sz, const T& c);

ここで、最初のデフォルトは要素を構築 (または値を初期化)szします。

于 2012-07-10T11:39:16.483 に答える