web-dev-qa-db-ja.com

std :: unordered_mapの等価性は挿入順序に依存しますか

(等しくない)キーと値のペアの同じセットを使用して2つのstd::unordered_mapコンテナを作成し、異なる順序で挿入する場合(コンテナは同じ要素を保持しますが、潜在的に異なる順序で)、コンテナは保証されます等号演算子( operator== )に従って等しくなるコンテナ要素のハッシュコードと等値演算子は、実装に必要なすべての制約を満たしていると仮定しています。

34
Raedwald

はい、この場合、同等の値を返すことが保証されています。具体的な表現(N4659から、§[unord.req]/12)は次のとおりです。

2つの順序付けられていないコンテナabは、a.size() == b.size()の場合に等しいことを比較し、a.equal_range(Ea1)から取得した同等のキーグループ_[Ea1, Ea2)_ごとに、 b.equal_range(Ea1)trueを返すような、is_permutation(Ea1, Ea2, Eb1, Eb2)から取得した同等のキーグループ_[Eb1, Eb2)_が存在します。

そのため、一方のキー(および関連する値)が他方と同じ(ただし、異なる順序で並べ替えられている可能性がある)限り、等しいと比較されます。

30
Jerry Coffin

[unord.red]/12 から

2つの順序付けられていないコンテナabは、a.size() == b.size()の場合に等しいことを比較し、a.equal_­range(Ea1)から取得した同等のキーグループ_[Ea1, Ea2)_ごとに、 b.equal_­range(Ea1)trueを返すような、is_­permutation(Ea1, Ea2, Eb1, Eb2)から取得した同等のキーグループ_[Eb1, Eb2)_が存在します。 [...]

したがって、キーが同じでサイズが同じである限り、コンテナはキーの順序に関係なく同等に比較されます。

13
NathanOliver

以下は、std:unordered_map、operator ==、!=(std :: unordered_map)について cppreference.com からの引用です。

次の条件が満たされる場合、2つの順序付けられていないコンテナlhsとrhsの内容は等しくなります。

  • lhs.size()== rhs.size()
  • lhs.equal_range(lhs_eq1)から取得した同等の要素[lhs_eq1、lhs_eq2)の各グループは、次のプロパティを持つrhs.equal_range(rhs_eq1)から取得した他のコンテナ[rhs_eq1、rhs_eq2)に対応する同等の要素グループを持ちます。 .____。]
    • std :: distance(lhs_eq1、lhs_eq2)== std :: distance(rhs_eq1、rhs_eq2)。
    • std :: is_permutation(lhs_eq1、lhs_eq2、rhs_eq1)== true。

ご了承ください:

KeyまたはTがEqualityComparableでない場合、動作は未定義です。

HashとKeyEqualが(C++ 20まで)KeyEqualが(C++ 20以降)lhsとrhsで同じ動作をしない場合、またはKeyのoperator ==がパーティションの改良ではない場合の動作も未定義ですKeyEqualによって導入された等価キーグループ(つまり、operator ==を使用して等しいと比較される2つの要素が異なるパーティションに分類される場合)

最後に、考慮すべきことは複雑さです。

Value_typeのoperator ==のN呼び出し、key_eqによって返される述語の呼び出し、hash_functionによって返されるハッシュの呼び出しに比例します。平均的な場合は、最悪の場合はN2に比例し、Nはコンテナのサイズです。

したがって、両方の順序付けられていないマップのサイズが同じで、一方のコンテナの各キーがもう一方のプラスで検索され、見つかった場合、それらの値が比較され、同じと見なされます。

3
acarlstein