std::ranges::copy_n() 算法
- 自 C++20 起
- 简化
- 详细
// (1)
constexpr copy_n_result<I, O>
copy_n( I first, std::iter_difference_t<I> n, O result );
参数类型是泛型的,并具有以下约束:
I
-std::input_iterator
O
-std::weakly_incrementable
此外,(1) 有以下约束
std::indirectly_copyable<I, O>
// (1)
template<
std::input_iterator I,
std::weakly_incrementable O
>
requires std::indirectly_copyable<I, O>
constexpr copy_n_result<I, O> copy_n( I first, std::iter_difference_t<I> n, O result );
辅助类型定义如下:
template< class I, class O >
using copy_n_result = ranges::in_out_result<I, O>;
- (1) 从以
first
开头的范围复制恰好n
个值到以result
开头的范围,方法是对于 [0
;n
) 中的每个整数,执行*(result + i) = *(first + i)
。
如果结果在范围 [first
; first + n
) 内,则行为未定义(在这种情况下,可以改用ranges::copy_backward
)。
本页描述的函数类实体是niebloids。
参数
first | 要从中复制的范围的开头。 |
n | 要复制的元素数量。 |
result | 目标范围的开头。 |
返回值
一个 copy_n_result
类型的对象,初始化如下:
{
first + n,
result + n
}
或更正式地说,一个包含以下内容的 ranges::in_out_result
类型的值:
- 等于
ranges::next(first, n)
的std::input_iterator
迭代器 - 以及等于
ranges::next(result, n)
的std::weakly_incrementable
迭代器
复杂度
恰好 n
次赋值。
异常
(无)
可能的实现
copy_n(1)
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 (std::iter_difference_t<I> i {}; i != n; ++i, ++first, ++result)
*result = *first;
return {std::move(first), std::move(result)};
}
};
inline constexpr copy_n_fn copy_n {};
备注
在实践中,如果值类型是 TriviallyCopyable
且迭代器类型满足 LegacyContiguousIterator
,则 std::copy
的实现会避免多次赋值,并使用批量复制函数,例如 std::memmove
。
当复制重叠范围时,ranges::copy
适用于向左复制(目标范围的开头在源范围之外),而 ranges::copy_backward
适用于向右复制(目标范围的末尾在源范围之外)。
示例
#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());
std::cout
<< "*(res.in): '" << *(res.in) << "', distance: "
<< std::distance(std::begin(in), res.in) << '\n'
<< "*(res.out): '" << *(res.out) << "', distance: "
<< std::distance(std::begin(out), res.out) << '\n';
}
"ABCD"
*(res.in): 'F', distance: 5
*(res.out): 'f', distance: 5