web-dev-qa-db-ja.com

構築時にstd :: vectorのメモリを予約するにはどうすればよいですか?

通常、私はそれを構築した直後にstd::vectorreserveを呼び出します。これにより、通常、std::vectorの既存のヒープ割り当てが破棄され、新しいヒープ割り当てに置き換えられませんか?ヒープスペースを割り当ててすぐに破棄するのではなく、構築時にメモリを予約する方法はありますか?または、これが問題にならないようにするためのstd::vector内の実装トリックはありますか?

使用可能なコンストラクターは、スペースを明示的に予約するのではなく、std::vectorに値を入力する場合にのみ役立つようです。

21
Richard Forrest

あなたの質問は、デフォルトで構築されたstd::vector<T>が[長さゼロ]の割り当てを実行するという誤った前提に基づいています。

文字通りそうする理由はありません。新しいベクトルの容量はzeroである必要があります(ただし、これは標準ではなく正気度によって要求されます)。

このように、あなたの目標はすでに本質的に満たされています。

率直に言って、標準ライブラリはthat愚かではありません。

皮肉な理由かもしれませんが、関数のシグネチャが不足しています。

要件は、ベクターに保存する要素の数を正確に知っているという使用シナリオに由来しますが、n-重複要素コンストラクターは本当に好きではありません。

_std::vector( size_type count, const T& value = T())
_

残念ながら、署名は上記のコンストラクターによって占有されています。その他の可能な署名は問題を引き起こす可能性があります。例えば。

  1. vector(size_type count, size_type reserve_count)は、T(size_type)のベクトルの上記のn個の重複要素コンストラクターと競合します。

  2. vector(size_type count, const T& value = T(), size_type reserve_count)は可能な解決策ですが、長すぎて退屈です。 auto v = vector<T>(0, T(), reserve_count)の呼び出し中に使用しないデフォルト値を作成する必要があります

その他の実行可能な解決策:

  1. Make_pair/make_uniqueのような関数を提供します。

  2. Allocatorから派生したReserverを定義するため、次のようなコンストラクターvector(const Allocator&alloc)を使用できます。

auto v = vector<Type>(new Reserver(reserve_count));

0
expect00

コンパイル時に要素の数がわかっている場合は、次のような要素を使用してベクトルをリスト初期化できます。

 class MyClass 
 {
      int x, y, z;
      std::vector<int> v;

  public:
         MyClass(int X, int Y, int Z) : x(X), y(Y), z(Z), v{x, y, z}
         {}
 };

しかし、これを維持するのはあまり良いことではありません。たとえば、事前に割り当てられたメモリプールからメモリを取得できるstd::vectorを使用できるカスタムアロケータなど、より高度な手法があります。ただし、本当に必要かどうかはわかりません。最新の実装では、非常に単純な問題を簡単に最適化できます。

0
edmz