跳到主要内容

std::copy_n() 算法

// (1)
template< class InputIt, class Size, class OutputIt >
constexpr OutputIt copy_n( InputIt first, Size count, OutputIt result );

// (2)
template< class ExecutionPolicy, class ForwardIt1, class Size, class ForwardIt2 >
ForwardIt2 copy_n( ExecutionPolicy&& policy,
ForwardIt1 first, Size count, ForwardIt2 result );

count 个元素从一个范围复制到新位置。

  • (1) 从以 first 开始的范围复制精确的 count 个值到以 result 开始的范围。形式上,对于每个整数 0 ≤ i < count,执行 *(result + i) = *(first + i)

    警告

    范围重叠在形式上是允许的,但会导致结果的顺序不可预测。

  • (2)(1),但根据策略执行。

    重载决议

    这些重载只有在 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>  (直到 C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>  (自 C++20 起)true 时才参与重载决议。

参数

first

要复制的范围的起始。

count

要复制的元素数量。

result

目标范围的开头。

policy

要使用的执行策略。有关详细信息,请参阅执行策略

类型要求

InputItLegacyInputIterator
OutputItLegacyOutputIterator
ForwardIt1
ForwardIt2
LegacyForwardIterator

返回值

目标范围中的迭代器,如果 count > 0 则指向复制的最后一个元素之后,否则指向 result

复杂度

  • 如果 count < 0 - 零次赋值
  • 否则 count 次赋值。

异常

带有模板参数 ExecutionPolicy 的重载报告错误如下

  • 如果作为算法一部分调用的函数执行抛出异常,并且 ExecutionPolicy标准策略之一,则调用std::terminate。对于任何其他 ExecutionPolicy,行为是实现定义的.
  • 如果算法未能分配内存,则抛出 std::bad_alloc

可能的实现

copy_n (1)

template<class InputIt, class Size, class OutputIt>
constexpr //< since C++20
OutputIt copy_n(InputIt first, Size count, OutputIt result)
{
if (count > 0)
{
*result = *first;
++result;
for (Size i = 1; i != count; ++i, ++result)
*result = *++first;
}

return result;
}

示例

Main.cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <vector>

int main()
{
std::string in {"1234567890"};
std::string out;

std::copy_n(in.begin(), 4, std::back_inserter(out));
std::cout << out << '\n';

std::vector<int> v_in(128);
std::iota(v_in.begin(), v_in.end(), 1);
std::vector<int> v_out(v_in.size());

std::copy_n(v_in.cbegin(), 100, v_out.begin());
std::cout << std::accumulate(v_out.begin(), v_out.end(), 0) << '\n';
}
输出
1234
5050
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”查看本文档所做的所有更改。
悬停查看原始许可证。

std::copy_n() 算法

// (1)
template< class InputIt, class Size, class OutputIt >
constexpr OutputIt copy_n( InputIt first, Size count, OutputIt result );

// (2)
template< class ExecutionPolicy, class ForwardIt1, class Size, class ForwardIt2 >
ForwardIt2 copy_n( ExecutionPolicy&& policy,
ForwardIt1 first, Size count, ForwardIt2 result );

count 个元素从一个范围复制到新位置。

  • (1) 从以 first 开始的范围复制精确的 count 个值到以 result 开始的范围。形式上,对于每个整数 0 ≤ i < count,执行 *(result + i) = *(first + i)

    警告

    范围重叠在形式上是允许的,但会导致结果的顺序不可预测。

  • (2)(1),但根据策略执行。

    重载决议

    这些重载只有在 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>  (直到 C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>  (自 C++20 起)true 时才参与重载决议。

参数

first

要复制的范围的起始。

count

要复制的元素数量。

result

目标范围的开头。

policy

要使用的执行策略。有关详细信息,请参阅执行策略

类型要求

InputItLegacyInputIterator
OutputItLegacyOutputIterator
ForwardIt1
ForwardIt2
LegacyForwardIterator

返回值

目标范围中的迭代器,如果 count > 0 则指向复制的最后一个元素之后,否则指向 result

复杂度

  • 如果 count < 0 - 零次赋值
  • 否则 count 次赋值。

异常

带有模板参数 ExecutionPolicy 的重载报告错误如下

  • 如果作为算法一部分调用的函数执行抛出异常,并且 ExecutionPolicy标准策略之一,则调用std::terminate。对于任何其他 ExecutionPolicy,行为是实现定义的.
  • 如果算法未能分配内存,则抛出 std::bad_alloc

可能的实现

copy_n (1)

template<class InputIt, class Size, class OutputIt>
constexpr //< since C++20
OutputIt copy_n(InputIt first, Size count, OutputIt result)
{
if (count > 0)
{
*result = *first;
++result;
for (Size i = 1; i != count; ++i, ++result)
*result = *++first;
}

return result;
}

示例

Main.cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <vector>

int main()
{
std::string in {"1234567890"};
std::string out;

std::copy_n(in.begin(), 4, std::back_inserter(out));
std::cout << out << '\n';

std::vector<int> v_in(128);
std::iota(v_in.begin(), v_in.end(), 1);
std::vector<int> v_out(v_in.size());

std::copy_n(v_in.cbegin(), 100, v_out.begin());
std::cout << std::accumulate(v_out.begin(), v_out.end(), 0) << '\n';
}
输出
1234
5050
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”查看本文档所做的所有更改。
悬停查看原始许可证。