std::copy, std::copy_if
| ヘッダー <algorithm> で定義 |
||
template< class InputIt, class OutputIt > OutputIt copy( InputIt first, InputIt last, |
(1) | (C++20 以降 constexpr) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 > |
(2) | (C++17以降) |
template< class InputIt, class OutputIt, class UnaryPred > OutputIt copy_if( InputIt first, InputIt last, |
(3) | (C++11以降) (C++20 以降 constexpr) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class UnaryPred > |
(4) | (C++17以降) |
[first, last) で定義された範囲の要素を、d_first から始まる別の範囲 (コピー先範囲) にコピーします。
[first, last) の範囲のすべての要素を、first から last へ順にコピーします。|
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以降) |
[first, last) とコピー先範囲が重なる場合、動作は未定義です。[first, last) とコピー先範囲が重なる場合、動作は未定義です。|
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以降) |
目次 |
[編集] パラメーター
| first, last | - | コピーする要素のソース 範囲 を定義するイテレータペア |
| d_first | - | コピー先範囲の先頭 |
| policy | - | 使用する 実行ポリシー |
| pred | - | 必要な要素に対して true を返す単項述語。 式 pred(v) は、型 (const の可能性あり) |
| 型要件 | ||
-InputIt は LegacyInputIterator の要件を満たす必要があります。 | ||
-OutputIt は LegacyOutputIterator の要件を満たさなければなりません。 | ||
-ForwardIt1, ForwardIt2 は LegacyForwardIterator の要件を満たさなければなりません。 | ||
-UnaryPred は Predicate の要件を満たさなければなりません。 | ||
[編集] 戻り値
コピーされた最後の要素の次を指す、コピー先範囲の出力イテレータ。
[編集] 計算量
std::distance(first, last) を N とする
ExecutionPolicy を持つオーバーロードの場合、ForwardIt1 の値型が MoveConstructible でない場合、パフォーマンスコストが発生する可能性があります。
[編集] 例外
ExecutionPolicy というテンプレートパラメータを持つオーバーロードは、次のようにエラーを報告します。
- アルゴリズムの一部として呼び出された関数の実行が例外をスローし、
ExecutionPolicyが 標準ポリシー のいずれかである場合、std::terminate が呼び出されます。その他のExecutionPolicyの場合、動作は実装定義です。 - アルゴリズムがメモリの割り当てに失敗した場合、std::bad_alloc がスローされます。
[編集] 可能な実装
| copy (1) |
|---|
template<class InputIt, class OutputIt> OutputIt copy(InputIt first, InputIt last, OutputIt d_first) { for (; first != last; (void)++first, (void)++d_first) *d_first = *first; return d_first; } |
| copy_if (3) |
template<class InputIt, class OutputIt, class UnaryPred> OutputIt copy_if(InputIt first, InputIt last, OutputIt d_first, UnaryPred pred) { for (; first != last; ++first) if (pred(*first)) { *d_first = *first; ++d_first; } return d_first; } |
[編集] 備考
実際には、std::copy の実装では、値型が TriviallyCopyable であり、イテレータ型が LegacyContiguousIterator を満たす場合、複数の代入を避け、std::memmove などの一括コピー関数を使用します。
重なる範囲をコピーする場合、std::copy は左側へコピーする場合 (コピー先範囲の先頭がソース範囲の外にある場合) に適しており、std::copy_backward は右側へコピーする場合 (コピー先範囲の末尾がソース範囲の外にある場合) に適しています。
[編集] 例
以下のコードは、ある std::vector の内容を別の std::vector にコピーし、その結果の std::vector を表示するために、std::copy を使用しています。
#include <algorithm> #include <iostream> #include <iterator> #include <numeric> #include <vector> int main() { std::vector<int> from_vector(10); std::iota(from_vector.begin(), from_vector.end(), 0); std::vector<int> to_vector; std::copy(from_vector.begin(), from_vector.end(), std::back_inserter(to_vector)); // or, alternatively, // std::vector<int> to_vector(from_vector.size()); // std::copy(from_vector.begin(), from_vector.end(), to_vector.begin()); // either way is equivalent to // std::vector<int> to_vector = from_vector; std::cout << "to_vector contains: "; std::copy(to_vector.begin(), to_vector.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << '\n'; std::cout << "odd numbers in to_vector are: "; std::copy_if(to_vector.begin(), to_vector.end(), std::ostream_iterator<int>(std::cout, " "), [](int x) { return x % 2 != 0; }); std::cout << '\n'; std::cout << "to_vector contains these multiples of 3: "; to_vector.clear(); std::copy_if(from_vector.begin(), from_vector.end(), std::back_inserter(to_vector), [](int x) { return x % 3 == 0; }); for (const int x : to_vector) std::cout << x << ' '; std::cout << '\n'; }
実行結果の例
to_vector contains: 0 1 2 3 4 5 6 7 8 9 odd numbers in to_vector are: 1 3 5 7 9 to_vector contains these multiples of 3: 0 3 6 9
[編集] 欠陥レポート
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 2039 | C++11 | std::copy_if の戻り値が指定されていなかった |
指定された |
| LWG 2044 | C++11 | std::copy_if の安定性が定義されていなかった |
defined |
[編集] 関連項目
| 要素の範囲を逆順にコピーする (関数テンプレート) | |
| 逆順になった範囲のコピーを作成する (関数テンプレート) | |
| (C++11) |
指定された数の要素を新しい場所にコピーする (関数テンプレート) |
| 範囲内のすべての要素に指定された値をコピー代入する (関数テンプレート) | |
| 特定の基準を満たす要素を除外して範囲をコピーする (関数テンプレート) | |
| (C++20)(C++20) |
要素の範囲を新しい場所にコピーする (アルゴリズム関数オブジェクト) |