std::unique_copy
| ヘッダー <algorithm> で定義 |
||
| template< class InputIt, class OutputIt > OutputIt unique_copy( InputIt first, InputIt last, OutputIt d_first ); |
(1) | (C++20 以降 constexpr) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 > ForwardIt2 unique_copy( ExecutionPolicy&& policy, ForwardIt1 first, |
(2) | (C++17以降) |
| template< class InputIt, class OutputIt, class BinaryPred > OutputIt unique_copy( InputIt first, InputIt last, |
(3) | (C++20 以降 constexpr) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryPred > |
(4) | (C++17以降) |
範囲 [first, last) の要素を、連続する等しい要素がないように、d_first で始まる別の範囲にコピーします。等しい要素のグループからは、最初の要素のみがコピーされます。
|
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> が true である。 |
(C++20まで) |
|
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> は true です。 |
(C++20以降) |
もし *d_first = *first が無効(C++20まで)*first を d_first に書き込むことができない(C++20以降)、プログラムは不正形式となります。
ソース範囲とデスティネーション範囲が重複する場合、動作は未定義です。
InputIt の値型を T とすると、オーバーロード (1) または (3) が以下のすべての条件を満たさない場合、動作は未定義です。
|
(C++20まで) |
|
(C++20以降) |
-
Tは CopyConstructible かつ CopyAssignable です。 - 以下のすべての条件が満たされます
-
OutputItは LegacyForwardIterator の要件を満たします。 OutputItの値型もTです。-
Tは CopyAssignable です。
-
目次 |
[編集] パラメータ
| first, last | - | 処理する要素のソース範囲を定義するイテレータのペア |
| d_first | - | コピー先範囲の先頭 |
| policy | - | 使用する 実行ポリシー |
| p | - | 要素が等しいと見なされる場合に true を返す二項述語。 述語関数のシグネチャは、以下と同等である必要がある。 bool pred(const Type1 &a, const Type2 &b); シグネチャは const & を持つ必要はないが、関数は渡されたオブジェクトを変更してはならず、値カテゴリに関わらず、(おそらく const の) |
| 型要件 | ||
-InputIt は LegacyInputIterator の要件を満たす必要があります。 | ||
-OutputIt は LegacyOutputIterator の要件を満たさなければなりません。 | ||
-ForwardIt1, ForwardIt2 は LegacyForwardIterator の要件を満たさなければなりません。 | ||
[編集] 戻り値
最後に書き込まれた要素の次の要素を指す出力イテレータ。
[編集] 計算量
std::distance(first, last) を N とする
オーバーロード (2,4) では、ForwardIt1 の値型が CopyConstructible かつ CopyAssignable の両方でない場合、パフォーマンスコストがかかる可能性があります。
[編集] 例外
ExecutionPolicy というテンプレートパラメータを持つオーバーロードは、次のようにエラーを報告します。
- アルゴリズムの一部として呼び出された関数の実行が例外をスローし、
ExecutionPolicyが 標準ポリシー のいずれかである場合、std::terminate が呼び出されます。その他のExecutionPolicyの場合、動作は実装定義です。 - アルゴリズムがメモリの割り当てに失敗した場合、std::bad_alloc がスローされます。
[編集] 可能な実装
実装については、libstdc++ および libc++ を参照してください。
[編集] 注記
InputIt が LegacyForwardIterator を満たす場合、この関数は重複を検出するために、入力元を再度読み取ります。
それ以外の場合、OutputIt が LegacyForwardIterator を満たし、InputIt の値型が OutputIt の値型と同じ場合、この関数は *d_first と *first を比較します。
それ以外の場合、この関数は *first とローカルな要素のコピーを比較します。
[編集] 例
#include <algorithm> #include <iostream> #include <iterator> #include <string> int main() { std::string s1 {"A string with mmmany letters!"}; std::cout << "Before: " << s1 << '\n'; std::string s2; std::unique_copy(s1.begin(), s1.end(), std::back_inserter(s2), [](char c1, char c2) { return c1 == 'm' && 'm' == c2; }); std::cout << "After: " << s2 << '\n'; }
出力
Before: A string with mmmany letters! After: A string with many letters!
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 239 | C++98 | 述語が std::distance(first, last) 回適用された | 1回少なく適用された (空でない範囲の場合) |
| LWG 241 | C++98 | InputIt の値型は CopyConstructible である必要はなかった |
条件付きで要求された |
| LWG 538 | C++98 | InputIt の値型は CopyAssignable である必要はなかった |
条件付きで要求された |
| LWG 2439 | C++98 | InputIt の値型はCopyConstructible である必要はなかった( OutputIt が LegacyForwardIterator の場合) |
条件付きで要求された |
[編集] 関連項目
| 等しい(または指定された述語を満たす)最初の2つの隣接する項目を見つける (関数テンプレート) | |
| 範囲内の連続する重複要素を削除する (関数テンプレート) | |
| (C++11) |
要素の範囲を新しい場所にコピーする (関数テンプレート) |
| (C++20) |
連続する重複を含まない要素の範囲のコピーを作成する (アルゴリズム関数オブジェクト) |