Skip to content

Commit

Permalink
unordered_map / setのerase : erase(iterator)のオーバーロードを追加
Browse files Browse the repository at this point in the history
  • Loading branch information
faithandbrave committed Jun 22, 2023
1 parent 6251e4a commit 217669c
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 95 deletions.
53 changes: 28 additions & 25 deletions reference/unordered_map/unordered_map/erase.md
Expand Up @@ -6,11 +6,13 @@
* cpp11[meta cpp]

```cpp
iterator erase(const_iterator position); // (1)
iterator erase(iterator position); // (1) C++17

size_type erase(const key_type& k); // (2)
iterator erase(const_iterator position); // (2) C++11

iterator erase(const_iterator first, const_iterator last); // (3)
size_type erase(const key_type& k); // (3) C++11

iterator erase(const_iterator first, const_iterator last); // (4) C++11
```
## 概要
Expand All @@ -24,30 +26,30 @@ iterator erase(const_iterator first, const_iterator last); // (3)
## 効果
- (1) : `position` で指定された要素を削除する。
- (2) : `k` と等価なキーの要素を削除する。
- (3) : イテレータ範囲`[first, last)` にある要素を全て削除する。
- (1), (2) : `position` で指定された要素を削除する。
- (3) : `k` と等価なキーの要素を削除する。
- (4) : イテレータ範囲`[first, last)` にある要素を全て削除する。
## 戻り値
- (1) : 「削除前に、削除された要素の次だった位置」を指すイテレータ。`erase()` を呼び出しても削除された要素以外を指す全てのイテレータは無効にならないため、`std::`[`next`](/reference/iterator/next.md)`(position)` と同じ位置を指す `iterator` である。
- (1), (2) : 「削除前に、削除された要素の次だった位置」を指すイテレータ。`erase()` を呼び出しても削除された要素以外を指す全てのイテレータは無効にならないため、`std::`[`next`](/reference/iterator/next.md)`(position)` と同じ位置を指す `iterator` である。
なお、`position` は `const_iterator` なのに対して、戻り値は `iterator` であるため注意が必要。
- (2) : 削除した要素数。つまり、`k` と等価なキーの要素があれば 1、無ければ 0。
- (3) : 「削除前に、削除された要素の範囲の次だった位置」を指すイテレータ。`erase()` を呼び出しても削除された要素以外を指す全てのイテレータは無効にならないため、`last` と同じ位置を指す `iterator` である。
- (3) : 削除した要素数。つまり、`k` と等価なキーの要素があれば 1、無ければ 0。
- (4) : 「削除前に、削除された要素の範囲の次だった位置」を指すイテレータ。`erase()` を呼び出しても削除された要素以外を指す全てのイテレータは無効にならないため、`last` と同じ位置を指す `iterator` である。
なお、`first` 及び `last` は `const_iterator` なのに対して、戻り値は `iterator` であるため注意が必要である。
また、要件に示したように `first` が間接参照可能である必要がなかった場合にも、他の種類のコンテナの戻り値と照らし合わせると、`last` と同じ位置を指す `iterator` を返すのが適切であるものと思われる。
## 例外
- (1) : 投げない。
- (2) : コンテナの `key_equal` と `hasher` のオブジェクト(それぞれ `key_eq()` と `hash_function()` が返すオブジェクト)が例外を投げなければ、例外を投げない。
- (3) : 投げない。
- (1), (2) : 投げない。
- (3) : コンテナの `key_equal` と `hasher` のオブジェクト(それぞれ `key_eq()` と `hash_function()` が返すオブジェクト)が例外を投げなければ、例外を投げない。
- (4) : 投げない。
## 計算量
- (1) : 平均的なケースでは定数(O(`1`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
- (2) : 平均的なケースでは削除された要素数に比例(O([`count`](count.md)`(k)`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
- (3) : 平均的なケースでは指定された範囲の要素数に比例(O(`std::`[`distance`](/reference/iterator/distance.md)`(first, last)`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
- (1), (2) : 平均的なケースでは定数(O(`1`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
- (3) : 平均的なケースでは削除された要素数に比例(O([`count`](count.md)`(k)`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
- (4) : 平均的なケースでは指定された範囲の要素数に比例(O(`std::`[`distance`](/reference/iterator/distance.md)`(first, last)`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
## 備考
Expand Down Expand Up @@ -94,10 +96,10 @@ int main()
std::cout << std::endl;
}
// 指定したキーと等価な要素を削除((2)の形式)
// 指定したキーと等価な要素を削除((3)の形式)
{
std::unordered_map<std::string, int> um{ {"1st", 1}, {"3rd", 3}, {"5th", 5}, {"7th", 7}, {"9th", 9}, };
print("(2) erase(const value_type&) before", um);
print("(3) erase(const value_type&) before", um);
auto count1 = um.erase("5th");
auto count2 = um.erase("8th");
Expand All @@ -107,10 +109,10 @@ int main()
std::cout << std::endl;
}
// 指定した位置にある要素を削除((3)の形式)
// 指定した位置にある要素を削除((4)の形式)
{
std::unordered_map<std::string, int> um{ {"1st", 1}, {"3rd", 3}, {"5th", 5}, {"7th", 7}, {"9th", 9}, };
print("(3) erase(const_iterator, const_iterator) before", um);
print("(4) erase(const_iterator, const_iterator) before", um);
auto it1 = std::next(um.cbegin());
auto it2 = std::next(it1, 2);
Expand All @@ -135,12 +137,12 @@ argument: (3rd, 3)
return value: (1st, 1)
after : (9th, 9), (7th, 7), (5th, 5), (1st, 1),
(2) erase(const value_type&) before : (9th, 9), (7th, 7), (5th, 5), (3rd, 3), (1st, 1),
(3) erase(const value_type&) before : (9th, 9), (7th, 7), (5th, 5), (3rd, 3), (1st, 1),
argument: 5th, 8th
return value: 1, 0
after : (9th, 9), (7th, 7), (3rd, 3), (1st, 1),
(3) erase(const_iterator, const_iterator) before : (9th, 9), (7th, 7), (5th, 5), (3rd, 3), (1st, 1),
(4) erase(const_iterator, const_iterator) before : (9th, 9), (7th, 7), (5th, 5), (3rd, 3), (1st, 1),
arguments: (7th, 7), (3rd, 3)
return value: (3rd, 3)
after : (9th, 9), (3rd, 3), (1st, 1),
Expand Down Expand Up @@ -200,10 +202,6 @@ int main()
- [Visual C++](/implementation.md#visual_cpp): ?


## 参照
- [N2350 Container insert/erase and iterator constness (Revision 1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2350.pdf)


## 関連項目

| 名前 | 説明 |
Expand All @@ -214,3 +212,8 @@ int main()
| [`clear`](clear.md) | 全要素の削除 |
| [`swap`](swap.md) | 内容の交換 |


## 参照
- [N2350 Container insert/erase and iterator constness (Revision 1)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2350.pdf)
- [LWG Issue 2059. C++0x ambiguity problem with `map::erase`](https://cplusplus.github.io/LWG/issue2059)
- C++17で、`erase(iterator)`を追加
48 changes: 25 additions & 23 deletions reference/unordered_map/unordered_multimap/erase.md
Expand Up @@ -6,11 +6,13 @@
* cpp11[meta cpp]

```cpp
iterator erase(const_iterator position); // (1)
iterator erase(iterator position); // (1) C++17

size_type erase(const key_type& k); // (2)
iterator erase(const_iterator position); // (2) C++11

iterator erase(const_iterator first, const_iterator last); // (3)
size_type erase(const key_type& k); // (3) C++11

iterator erase(const_iterator first, const_iterator last); // (4) C++11
```
## 概要
Expand All @@ -24,30 +26,30 @@ iterator erase(const_iterator first, const_iterator last); // (3)
## 効果
- (1) : `position` で指定された要素を削除する。
- (2) : `k` と等価なキーの要素を削除する。
- (3) : イテレータ範囲`[first, last)` にある要素を全て削除する。
- (1), (2) : `position` で指定された要素を削除する。
- (3) : `k` と等価なキーの要素を削除する。
- (4) : イテレータ範囲`[first, last)` にある要素を全て削除する。
## 戻り値
- (1) : 「削除前に、削除された要素の次だった位置」を指すイテレータ。`erase()` を呼び出しても削除された要素以外を指す全てのイテレータは無効にならないため、`std::`[`next`](/reference/iterator/next.md)`(position)` と同じ位置を指す `iterator` である。
- (1), (2) : 「削除前に、削除された要素の次だった位置」を指すイテレータ。`erase()` を呼び出しても削除された要素以外を指す全てのイテレータは無効にならないため、`std::`[`next`](/reference/iterator/next.md)`(position)` と同じ位置を指す `iterator` である。
なお、`position` は `const_iterator` なのに対して、戻り値は `iterator` であるため注意が必要である。
- (2) : 削除した要素数。
- (3) : 「削除前に、削除された要素の範囲の次だった位置」を指すイテレータ。`erase()` を呼び出しても削除された要素以外を指す全てのイテレータは無効にならないため、`last` と同じ位置を指す `iterator` である。
- (3) : 削除した要素数。
- (4) : 「削除前に、削除された要素の範囲の次だった位置」を指すイテレータ。`erase()` を呼び出しても削除された要素以外を指す全てのイテレータは無効にならないため、`last` と同じ位置を指す `iterator` である。
なお、`first` 及び `last` は `const_iterator` なのに対して、戻り値は `iterator` であるため注意が必要である。
また、要件に示したように `first` が間接参照可能である必要がなかった場合にも、他の種類のコンテナの戻り値と照らし合わせると、`last` と同じ位置を指す `iterator` を返すのが適切であるものと思われる。
## 例外
- (1) : 投げない。
- (2) : コンテナの `key_equal` と `hasher` のオブジェクト(それぞれ `key_eq()` と `hash_function()` が返すオブジェクト)が例外を投げなければ、例外を投げない。
- (3) : 投げない。
- (1), (2) : 投げない。
- (3) : コンテナの `key_equal` と `hasher` のオブジェクト(それぞれ `key_eq()` と `hash_function()` が返すオブジェクト)が例外を投げなければ、例外を投げない。
- (4) : 投げない。
## 計算量
- (1) : 平均的なケースでは定数(O(`1`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
- (2) : 平均的なケースでは削除された要素数に比例(O([`count`](count.md)`(k)`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
- (3) : 平均的なケースでは指定された範囲の要素数に比例(O(`std::`[`distance`](/reference/iterator/distance.md)`(first, last)`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
- (1), (2) : 平均的なケースでは定数(O(`1`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
- (3) : 平均的なケースでは削除された要素数に比例(O([`count`](count.md)`(k)`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
- (4) : 平均的なケースでは指定された範囲の要素数に比例(O(`std::`[`distance`](/reference/iterator/distance.md)`(first, last)`))だが、最悪のケースではコンテナの要素数に比例(O([`size`](size.md)`()`))
## 備考
Expand Down Expand Up @@ -94,10 +96,10 @@ int main()
std::cout << std::endl;
}
// 指定したキーと等価な要素を削除((2)の形式)
// 指定したキーと等価な要素を削除((3)の形式)
{
std::unordered_multimap<std::string, int> um{ {"1st", 1}, {"3rd", 3}, {"5th", 5}, {"7th", 7}, {"9th", 9}, {"3rd", 33}, };
print("(2) erase(const value_type&) before", um);
print("(3) erase(const value_type&) before", um);
auto count1 = um.erase("5th");
auto count2 = um.erase("8th");
Expand All @@ -108,10 +110,10 @@ int main()
std::cout << std::endl;
}
// 指定した位置にある要素を削除((3)の形式)
// 指定した位置にある要素を削除((4)の形式)
{
std::unordered_multimap<std::string, int> um{ {"1st", 1}, {"3rd", 3}, {"5th", 5}, {"7th", 7}, {"9th", 9}, {"3rd", 33}, };
print("(3) erase(const_iterator, const_iterator) before", um);
print("(4) erase(const_iterator, const_iterator) before", um);
auto it1 = std::next(um.cbegin());
auto it2 = std::next(it1, 2);
Expand All @@ -136,12 +138,12 @@ argument: (3rd, 33)
return value: (3rd, 3)
after : (9th, 9), (7th, 7), (5th, 5), (3rd, 3), (1st, 1),
(2) erase(const value_type&) before : (9th, 9), (7th, 7), (5th, 5), (3rd, 33), (3rd, 3), (1st, 1),
(3) erase(const value_type&) before : (9th, 9), (7th, 7), (5th, 5), (3rd, 33), (3rd, 3), (1st, 1),
argument: 5th, 8th, 3rd
return value: 1, 0, 2
after : (9th, 9), (7th, 7), (1st, 1),
(3) erase(const_iterator, const_iterator) before : (9th, 9), (7th, 7), (5th, 5), (3rd, 33), (3rd, 3), (1st, 1),
(4) erase(const_iterator, const_iterator) before : (9th, 9), (7th, 7), (5th, 5), (3rd, 33), (3rd, 3), (1st, 1),
arguments: (7th, 7), (3rd, 33)
return value: (3rd, 33)
after : (9th, 9), (3rd, 33), (3rd, 3), (1st, 1),
Expand Down Expand Up @@ -215,5 +217,5 @@ int main()
## 参照
- [LWG Issue 518. Are `insert` and `erase` stable for `unordered_multiset` and `unordered_multimap`?](http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#518)
- 安定性の保証が規定された経緯のレポート


- [LWG Issue 2059. C++0x ambiguity problem with `map::erase`](https://cplusplus.github.io/LWG/issue2059)
- C++17で、`erase(iterator)`を追加

0 comments on commit 217669c

Please sign in to comment.