std::ranges::copy_n、std::ranges::copy_n_result
From cppreference.com
| ヘッダー <algorithm> で定義 |
||
| 呼び出しシグネチャ |
||
| template< std::input_iterator I, std::weakly_incrementable O > requires std::indirectly_copyable<I, O> |
(1) | (C++20以降) |
| ヘルパー型 |
||
| template< class I, class O > using copy_n_result = ranges::in_out_result<I, O>; |
(2) | (C++20以降) |
1) rangeの先頭 first から range の先頭 result へ、整数
[0, n) の各整数 i について *(result + i) = *(first + i) を実行して、ちょうど n 個の値をコピーします。 result が [first, first + n) の範囲内にある場合、動作は未定義です(この場合、代わりに ranges::copy_backward が使用される可能性があります)。このページで説明されている関数のようなエンティティは、アルゴリズム関数オブジェクト(非公式にはニーブロイドとして知られている)です。つまり、
- これらのいずれかを呼び出す際に、明示的なテンプレート引数リストを指定することはできません。
- これらのいずれも実引数依存の名前探索には見えません。
- これらのいずれかが関数呼び出し演算子の左側の名前として通常の非修飾名探索によって見つかった場合、実引数依存の名前探索は抑制されます。
目次 |
[edit] Parameters
| first | - | コピー元の要素の範囲の開始位置 |
| n | - | コピーする要素の数 |
| 結果 | - | コピー先範囲の先頭 |
[edit] Return value
ranges::copy_n_result{first + n, result + n}、またはより正式には、input_iterator ranges::next(first, n) に等しいイテレータと、weakly_incrementable ranges::next(result, n) に等しいイテレータを含む ranges::in_out_result 型の値。
[edit] Complexity
ちょうど n 回の代入。
[edit] Notes
実際には、std::ranges::copy_n の実装は、値の型が TriviallyCopyable で、イテレータ型が contiguous_iterator を満たす場合、複数の代入を回避し、std::memmove のようなバルクコピー関数を使用する場合があります。あるいは、コンパイラの最適化フェーズ中にそのようなコピー高速化が注入されることもあります。
重複する範囲をコピーする場合、std::ranges::copy_n は左方向へのコピー(宛先範囲の開始位置がソース範囲の外側にある場合)に適していますが、std::ranges::copy_backward は右方向へのコピー(宛先範囲の終了位置がソース範囲の外側にある場合)に適しています。
[edit] Possible implementation
struct copy_n_fn { template<std::input_iterator I, std::weakly_incrementable O> requires std::indirectly_copyable<I, O> constexpr ranges::copy_n_result<I, O> operator()(I first, std::iter_difference_t<I> n, O result) const { for (; n-- > 0; (void)++first, (void)++result) *result = *first; return {std::move(first), std::move(result)}; } }; inline constexpr copy_n_fn copy_n{}; |
[edit] Example
このコードを実行
#include <algorithm> #include <iomanip> #include <iostream> #include <iterator> #include <string> #include <string_view> int main() { const std::string_view in{"ABCDEFGH"}; std::string out; std::ranges::copy_n(in.begin(), 4, std::back_inserter(out)); std::cout << std::quoted(out) << '\n'; out = "abcdefgh"; const auto res{std::ranges::copy_n(in.begin(), 5, out.begin())}; const auto i{std::distance(std::begin(in), res.in)}; const auto j{std::distance(std::begin(out), res.out)}; std::cout << "in[" << i << "] = '" << in[i] << "'\n" << "out[" << j << "] = '" << out[j] << "'\n"; }
出力
"ABCD" in[5] = 'F' out[5] = 'f'
[edit] See also
| (C++20)(C++20) |
要素の範囲を新しい場所にコピーする (アルゴリズム関数オブジェクト) |
| (C++20) |
要素の範囲を逆順にコピーする (アルゴリズム関数オブジェクト) |
| (C++20)(C++20) |
特定の基準を満たす要素を除外して範囲をコピーする (アルゴリズム関数オブジェクト) |
| (C++20)(C++20) |
特定の基準を満たす要素を別の値に置き換えながら範囲をコピーする (アルゴリズム関数オブジェクト) |
| (C++20) |
逆順になった範囲のコピーを作成する (アルゴリズム関数オブジェクト) |
| (C++20) |
要素の範囲をコピーして回転させる (アルゴリズム関数オブジェクト) |
| (C++20) |
連続する重複を含まない要素の範囲のコピーを作成する (アルゴリズム関数オブジェクト) |
| (C++20) |
要素の範囲を新しい場所にムーブする (アルゴリズム関数オブジェクト) |
| (C++20) |
要素の範囲を逆順で新しい場所にムーブする (アルゴリズム関数オブジェクト) |
| (C++11) |
指定された数の要素を新しい場所にコピーする (関数テンプレート) |