別の質問が次の考えに影響を与えました。
容量を増やすときにすべての要素を移動する必要がありますstd::vector<T> か?
私が理解している限り、標準的な動作は、基礎となるアロケーターが新しいサイズのチャンク全体を要求し、次に古い要素をすべて移動し、古い要素を破棄してから古いメモリの割り当てを解除することです。
この動作は、標準のアロケータ インターフェイスを考えると、唯一可能な正しい解決策のようです。しかし、アロケーターを修正して、 a を返し、基になる にマップできるreallocate(std::size_t)関数を提供することは理にかなっているのでしょうか? これの利点は、OS が割り当てられたメモリを実際に拡張できる場合、移動がまったく発生しないことです。ブール値は、メモリが移動したかどうかを示します。pair<pointer, bool>realloc()
(std::realloc()拡張できない場合はデータをコピーする必要がないため、最良の選択ではない可能性があります。したがって、実際には のようなものが必要ですextend_or_malloc_new()。編集:おそらくis_pod-trait ベースの特殊化により、実際のrealloc,そのビット単位のコピーを含みます。一般的にはそうではありません。)
チャンスを逃したようです。最悪の場合、常にreallocate(size_t n)asを実装できるreturn make_pair(allocate(n), true);ため、ペナルティはありません。
この機能を C++ にとって不適切または望ましくないものにする問題はありますか?
おそらく、これを利用できる唯一のコンテナは ですがstd::vector、これも非常に便利なコンテナです。
更新: 明確にするための小さな例。現在resize():
pointer p = alloc.allocate(new_size);
for (size_t i = 0; i != old_size; ++i)
{
alloc.construct(p + i, T(std::move(buf[i])))
alloc.destroy(buf[i]);
}
for (size_t i = old_size; i < new_size; ++i)
{
alloc.construct(p + i, T());
}
alloc.deallocate(buf);
buf = p;
新しい実装:
pair<pointer, bool> pp = alloc.reallocate(buf, new_size);
if (pp.second) { /* as before */ }
else { /* only construct new elements */ }