std::ranges::copy、std::ranges::copy_if、std::ranges::copy_result、std::ranges::copy_if_result
| ヘッダー <algorithm> で定義 |
||
| 呼び出しシグネチャ |
||
template< std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O > requires std::indirectly_copyable<I, O> |
(1) | (C++20以降) |
| template< ranges::input_range R, std::weakly_incrementable O > requires std::indirectly_copyable<ranges::iterator_t<R>, O> |
(2) | (C++20以降) |
template< std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O, class Proj = std::identity, |
(3) | (C++20以降) |
| template< ranges::input_range R, std::weakly_incrementable O, class Proj = std::identity, |
(4) | (C++20以降) |
| ヘルパー型 |
||
| template< class I, class O > using copy_result = ranges::in_out_result<I, O>; |
(5) | (C++20以降) |
| template< class I, class O > using copy_if_result = ranges::in_out_result<I, O>; |
(6) | (C++20以降) |
range [first, last)で定義された要素の範囲を、resultで始まる別の範囲にコピーします。
[first, last)の範囲内のすべての要素を、firstから開始し、last - 1まで進行させてコピーします。 resultが範囲 [first, last)内にある場合、動作は未定義です。この場合、代わりにranges::copy_backwardを使用できます。このページで説明されている関数のようなエンティティは、アルゴリズム関数オブジェクト(非公式にはニーブロイドとして知られている)です。つまり、
- これらのいずれかを呼び出す際に、明示的なテンプレート引数リストを指定することはできません。
- これらのいずれも実引数依存の名前探索には見えません。
- これらのいずれかが関数呼び出し演算子の左側の名前として通常の非修飾名探索によって見つかった場合、実引数依存の名前探索は抑制されます。
目次 |
[編集] パラメータ
| first, last | - | コピーする要素の範囲を定義するイテレータ-センチネルペア |
| r | - | コピーする要素の範囲 |
| 結果 | - | 宛先範囲の開始位置。 |
| pred | - | 射影された要素に適用する述語 |
| proj | - | 要素に適用する射影 |
[編集] 戻り値
ranges::in_out_result。入力イテレータはlastに等しく、出力イテレータはコピーされた最後の要素の次を指します。
[編集] 計算量
[編集] 注記
実際には、ranges::copyの実装では複数の代入を避け、値型がTriviallyCopyableであり、イテレータ型がcontiguous_iteratorを満たす場合、std::memmoveのようなバルクコピー関数を使用します。
重複する範囲をコピーする場合、宛先範囲の開始位置がソース範囲の外側にある(左へのコピー)場合はranges::copyが適切であり、宛先範囲の終了位置がソース範囲の外側にある(右へのコピー)場合はranges::copy_backwardが適切です。
[編集] 可能な実装
| copy (1)(2) |
|---|
struct copy_fn { template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O> requires std::indirectly_copyable<I, O> constexpr ranges::copy_result<I, O> operator()(I first, S last, O result) const { for (; first != last; ++first, (void)++result) *result = *first; return {std::move(first), std::move(result)}; } template<ranges::input_range R, std::weakly_incrementable O> requires std::indirectly_copyable<ranges::iterator_t<R>, O> constexpr ranges::copy_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result) const { return (*this)(ranges::begin(r), ranges::end(r), std::move(result)); } }; inline constexpr copy_fn copy; |
| copy_if (3)(4) |
struct copy_if_fn { template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O, class Proj = std::identity, std::indirect_unary_predicate<std::projected<I, Proj>> Pred> requires std::indirectly_copyable<I, O> constexpr ranges::copy_if_result<I, O> operator()(I first, S last, O result, Pred pred, Proj proj = {}) const { for (; first != last; ++first) if (std::invoke(pred, std::invoke(proj, *first))) { *result = *first; ++result; } return {std::move(first), std::move(result)}; } template<ranges::input_range R, std::weakly_incrementable O, class Proj = std::identity, std::indirect_unary_predicate< std::projected<ranges::iterator_t<R>, Proj>> Pred> requires std::indirectly_copyable<ranges::iterator_t<R>, O> constexpr ranges::copy_if_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result, Pred pred, Proj proj = {}) const { return (*this)(ranges::begin(r), ranges::end(r), std::move(result), std::ref(pred), std::ref(proj)); } }; inline constexpr copy_if_fn copy_if; |
[編集] 例
次のコードは、ranges::copyを使用して、一方のstd::vectorの内容をもう一方にコピーし、結果のstd::vectorを表示します。
#include <algorithm> #include <iostream> #include <iterator> #include <numeric> #include <vector> int main() { std::vector<int> source(10); std::iota(source.begin(), source.end(), 0); std::vector<int> destination; std::ranges::copy(source.begin(), source.end(), std::back_inserter(destination)); // or, alternatively, // std::vector<int> destination(source.size()); // std::ranges::copy(source.begin(), source.end(), destination.begin()); // either way is equivalent to // std::vector<int> destination = source; std::cout << "Destination contains: "; std::ranges::copy(destination, std::ostream_iterator<int>(std::cout, " ")); std::cout << '\n'; std::cout << "Odd numbers in destination are: "; std::ranges::copy_if(destination, std::ostream_iterator<int>(std::cout, " "), [](int x) { return (x % 2) == 1; }); std::cout << '\n'; }
出力
Destination contains: 0 1 2 3 4 5 6 7 8 9 Odd numbers in destination are: 1 3 5 7 9
[編集] 関連項目
| (C++20) |
要素の範囲を逆順にコピーする (アルゴリズム関数オブジェクト) |
| (C++20) |
逆順になった範囲のコピーを作成する (アルゴリズム関数オブジェクト) |
| (C++20) |
指定された数の要素を新しい場所にコピーする (アルゴリズム関数オブジェクト) |
| (C++20) |
要素の範囲に特定の値を代入する (アルゴリズム関数オブジェクト) |
| (C++20)(C++20) |
特定の基準を満たす要素を除外して範囲をコピーする (アルゴリズム関数オブジェクト) |
| (C++11) |
要素の範囲を新しい場所にコピーする (関数テンプレート) |