命名空间
变体
操作

std::ranges::copy_n, std::ranges::copy_n_result

来自 cppreference.com
< cpp‎ | algorithm‎ | ranges
 
 
算法库
受约束的算法和范围上的算法 (C++20)
受约束的算法,例如 ranges::copy, ranges::sort, ...
执行策略 (C++17)
排序及相关操作
分区操作
排序操作
二分搜索操作
(在分区范围上)
集合操作(在排序范围上)
合并操作(在排序范围上)
堆操作
最小/最大操作
(C++11)
(C++17)
字典序比较操作
排列操作
C 库
数值操作
对未初始化内存的操作
 
受约束的算法
此菜单中的所有名称都属于命名空间 std::ranges
非修改序列操作
修改序列操作
分区操作
排序操作
二分搜索操作(在排序范围上)
       
       
集合操作(在排序范围上)
堆操作
最小/最大操作
       
       
排列操作
折叠操作
数值操作
(C++23)            
对未初始化存储的操作
返回类型
 
定义在头文件 <algorithm>
调用签名
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 );
(1) (自 C++20 起)
辅助类型
template< class I, class O >
using copy_n_result = ranges::in_out_result<I, O>;
(2) (自 C++20 起)
1) 将从以 first 开始的范围中,复制恰好 n 个值到以 result 开始的范围中,通过执行 *(result + i) = *(first + i)[0n) 中的每个整数执行。如果 result 位于范围 [firstfirst + n) 内,则行为未定义(在这种情况下,可以使用 ranges::copy_backward)。

此页面上描述的功能式实体是 niebloids,也就是说

在实践中,它们可以实现为函数对象,或者使用特殊的编译器扩展。

内容

[编辑] 参数

first - 要从中复制元素的范围的开头
n - 要复制的元素数量
result - 目标范围的开头

[编辑] 返回值

ranges::copy_n_result{first + n, result + n} 或者更正式地说,一个类型为 ranges::in_out_result 的值,其中包含一个 std::input_iterator 迭代器等于 ranges::next(first, n),并且一个 std::weakly_incrementable 迭代器等于 ranges::next(result, n)

[edit] 复杂度

正好 n 个赋值。

[edit] 注意

在实践中,std::ranges::copy_n 的实现可能会避免多次赋值,并使用诸如 std::memmove 之类的批量复制函数,如果值类型是 TriviallyCopyable 并且迭代器类型满足 contiguous_iterator。或者,这种复制加速可以在编译器的优化阶段注入。

在复制重叠范围时,当复制到左侧(目标范围的开头位于源范围之外)时,std::ranges::copy_n 是合适的,而当复制到右侧(目标范围的结尾位于源范围之外)时,std::ranges::copy_backward 是合适的。

[edit] 可能的实现

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 {};

[edit] 例子

#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

[edit] 参见

将一组元素复制到一个新的位置
(niebloid)[edit]
以反向顺序复制一组元素
(niebloid)[edit]
复制一组元素,省略满足特定条件的那些元素
(niebloid)[edit]
复制一个范围,用另一个值替换满足特定条件的元素
(niebloid)[edit]
创建一个反转的范围副本
(niebloid)[edit]
复制和旋转一组元素
(niebloid)[edit]
创建一个不包含连续重复元素的某些范围元素的副本
(niebloid)[edit]
将一组元素移动到一个新的位置
(niebloid)[edit]
以反向顺序将一组元素移动到一个新的位置
(niebloid)[edit]
(C++11)
将一定数量的元素复制到一个新的位置
(函数模板) [edit]