跳到主要内容

std::ranges::copy_n() 算法

// (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>

辅助类型定义如下:

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 适用于向右复制(目标范围的末尾在源范围之外)。

示例

Main.cpp
#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
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。

std::ranges::copy_n() 算法

// (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>

辅助类型定义如下:

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 适用于向右复制(目标范围的末尾在源范围之外)。

示例

Main.cpp
#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
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。