デストラクタを呼び出す必要があるため、clear() 操作の複雑さはコンテナのサイズに比例することを理解しています。しかし、プリミティブ型 (および POD) はどうでしょうか? 複雑さが一定になるように、ベクター サイズを 0 に設定するのが最善の方法のようです。
これが可能であれば、std::unordered_map でも可能ですか?
デストラクタを呼び出す必要があるため、clear() 操作の複雑さはコンテナのサイズに比例することを理解しています。しかし、プリミティブ型 (および POD) はどうでしょうか? 複雑さが一定になるように、ベクター サイズを 0 に設定するのが最善の方法のようです。
これが可能であれば、std::unordered_map でも可能ですか?
複雑さが一定になるように、ベクター サイズを 0 に設定するのが最善の方法のようです。
一般に、ベクトルを 0 にサイズ変更する複雑さは、現在 .xml に格納されている要素の数に比例しvector
ます。したがって、vector
のサイズを 0 に設定しても、呼び出しよりも利点はありませんclear()
。この 2 つは本質的に同じです。
ただし、少なくとも 1 つの実装 (libstdc++、 のソースbits/stl_vector.h
) では、部分的なテンプレートの特殊化を採用することで、プリミティブ型の複雑さが O(1) になります。
の実装は、重要なコンパイル時の最適化を実行する関数 inにclear()
移動します。それは type のテンプレート パラメータで補助テンプレート クラスを宣言します。このクラスには、 に対する部分的な特殊化と に対する明示的な特殊化があります。どちらの特殊化も、 と呼ばれる単一の静的関数を定義します。テンプレート パラメータが の場合、関数本体は空です。パラメータが の場合、ボディにはのデストラクタを呼び出すループが含まれます。std::_Destroy(from, to)
bits/stl_construct.h
_Destroy_aux
bool
true
false
__destroy
true
false
T
std::_Destroy(ptr)
トリックは136 行目にあります。
std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
__destroy(__first, __last);
__has_trivial_destructor
補助クラスは、チェックの結果に基づいてインスタンス化されます。チェッカーはtrue
、組み込み型、およびfalse
非自明なデストラクタを持つ型を返します。その結果、、、およびその他の POD タイプでは、 への呼び出し__destroy
はノーオペレーションになります。int
double
は、オブジェクト自体を削除するのではなく、POD オブジェクトの「ハッシュ バケット」を表す構造を削除する必要がある場合があるという点で とstd::unordered_map
は異なります*。toの最適化は可能ですが、実装に大きく依存するため、当てにはできません。vector
clear
O(1)
*正確な答えは実装によって異なります。オープン アドレス指定 (線形プローブ、二次プローブなど) に基づいた衝突解決を実装するハッシュ テーブルは、 内のすべてのバケットを削除できる場合がありO(1)
ます。ただし、個別の連鎖に基づく実装では、バケットを 1 つずつ削除する必要があります。
std::_Destroy
最終的に によって使用されるgcc のバージョンの はclear()
、型に自明なデストラクタがあるかどうかに基づいてテンプレートを作成しようとします。そのため、その場合、最適化パスがなくても複雑さは一定です。ただし、テンプレートがどの程度機能するかはわかりません。