命名空间
变体
操作

std::experimental::ranges::copy, std::experimental::ranges::copy_if

来自 cppreference.com
< cpp‎ | experimental‎ | ranges
 
 
实验性
技术规范
文件系统库 (文件系统 TS)
库基础 (库基础 TS)
库基础 2 (库基础 TS v2)
库基础 3 (库基础 TS v3)
并行扩展 (并行 TS)
并行扩展 2 (并行 TS v2)
并发扩展 (并发 TS)
并发扩展 2 (并发 TS v2)
概念 (概念 TS)
范围 (范围 TS)
反射 (反射 TS)
数学特殊函数 (特殊函数 TR)
实验性非 TS
模式匹配
线性代数
std::execution
契约
2D 图形
 
 
 
在头文件 <experimental/ranges/algorithm> 中定义
template< InputIterator I, Sentinel<I> S, WeaklyIncrementable O >

    requires IndirectlyCopyable<I, O>
ranges::tagged_pair<tag::in(I), tag::out(O)>

    copy( I first, S last, O result );
(1) (范围 TS)
template< InputRange R, WeaklyIncrementable O >

    requires IndirectlyCopyable<ranges::iterator_t<R>, O>
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>

    copy( R&& r, O result );
(2) (范围 TS)
template< InputIterator I, Sentinel<I> S, WeaklyIncrementable O,

          class Proj = ranges::identity,
          IndirectUnaryPredicate<projected<I, Proj>> Pred >
    requires IndirectlyCopyable<I, O>
ranges::tagged_pair<tag::in(I), tag::out(O)>

    copy_if( I first, S last, O result, Pred pred, Proj proj = Proj{} );
(3) (范围 TS)
template< InputRange R, WeaklyIncrementable O,

          class Proj = ranges::identity,
          IndirectUnaryPredicate<projected<ranges::iterator_t<R>, Proj>> Pred >
    requires IndirectlyCopyable<iterator_t<R>, O>
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>

    copy_if( R&& r, O result, Pred pred, Proj proj = Proj{} );
(4) (范围 TS)

将源范围 ([firstlast)r) 中的元素复制到从 result 开始的目标范围内,从源范围的第一个元素开始,一直到最后一个元素。

1) 复制范围 [firstlast) 中的所有元素。对于每个非负整数 n < (last - first),执行 *(result + n) = *(first + n)。如果 result 在范围 [firstlast) 内,则行为未定义。在这种情况下,可以使用 ranges::copy_backward 来代替。
2)(1) 相同,但使用 r 作为源范围,如同通过 ranges::copy(ranges::begin(r), ranges::end(r), result); 一样,只不过 result 可能不会被复制。
3) 只复制当谓词 pred 对通过投影 proj 投影的元素的值应用时返回 true 的元素。复制元素的顺序保持不变。如果源范围和目标范围重叠,则行为未定义。
4)(3) 相同,但使用 r 作为源范围,就像使用 ranges::copy_if(ranges::begin(r), ranges::end(r), result, pred, proj); 一样,除了 resultpredproj 可能不会被复制。

尽管上面描述了声明,但算法声明的实际模板参数数量和顺序未指定。因此,如果在调用算法时使用显式模板参数,程序可能无法移植。

内容

[编辑] 参数

first, last - 要复制的元素范围
r - 要复制的元素范围
result - 目标范围的起始位置
pred - 要应用于投影元素的谓词
proj - 要应用于元素的投影

[编辑] 返回值

包含以下两个成员的 tagged_pair 对象

  • 第一个成员,带有标记 tag::in,是源范围的末尾后迭代器(即类型为 I 的迭代器,与哨兵 last 相等)。
  • 第二个成员,带有标记 tag::out,是结果范围的末尾后迭代器。

[编辑] 复杂度

1) 恰好 ranges::distance(first, last) 次赋值。
2) 恰好 ranges::distance(r) 次赋值。
3) 恰好 ranges::distance(first, last) 次相应投影和谓词的应用。
4) 恰好 ranges::distance(r) 次相应投影和谓词的应用。

[编辑] 可能的实现

第一个版本
template<InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
    requires IndirectlyCopyable<I, O>()
ranges::tagged_pair<tag::in(I), tag::out(O)>
    copy(I first, S last, O result)
{
    for (; first != last; ++first, (void)++result)
        *result = *first;
    return {first, result};
}
第二个版本
template<InputRange R, WeaklyIncrementable O>
    requires IndirectlyCopyable<ranges::iterator_t<R>, O>()
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>
    copy(R&& r, O result)
{
   return ranges::copy(ranges::begin(r), ranges::end(r), result);
}
第三个版本
template<InputIterator I, Sentinel<I> S, WeaklyIncrementable O,
         class Proj = ranges::identity,
         IndirectUnaryPredicate<projected<I, Proj>> Pred>
    requires IndirectlyCopyable<I, O>()
ranges::tagged_pair<tag::in(I), tag::out(O)>
    copy_if(I first, S last, O result, Pred pred, Proj proj = Proj{})
{
    for (; first != last; ++first)
        if (ranges::invoke(pred, ranges::invoke(proj, *first)))
        {
            *result = *first;
            ++result;
        }
    return {first, result};
}
第四个版本
template<InputRange R, WeaklyIncrementable O,
         class Proj = ranges::identity,
         IndirectUnaryPredicate<projected<ranges::iterator_t<R>, Proj>> Pred>
    requires IndirectlyCopyable<ranges::iterator_t<R>, O>()
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>
    copy_if(R&& r, O result, Pred pred, Proj proj = Proj{})
{
    return ranges::copy_if(ranges::begin(r), ranges::end(r), result, pred, proj);
}

[编辑] 示例

以下代码使用 copy 将一个向量的内容复制到另一个向量,并显示结果向量

#include <experimental/ranges/algorithm>
#include <experimental/ranges/iterator>
#include <iostream>
#include <numeric>
#include <vector>
 
int main()
{
    // see https://cppreference.cn/w/cpp/language/namespace_alias
    namespace ranges = std::experimental::ranges;
 
    std::vector<int> from_vector(10);
    std::iota(from_vector.begin(), from_vector.end(), 0);
 
    std::vector<int> to_vector;
    ranges::copy_if(from_vector.begin(), from_vector.end(),
                    ranges::back_inserter(to_vector),
                    [](const auto i)
                    {
                       return i % 3;
                    });
// or, alternatively,
//  std::vector<int> to_vector(from_vector.size());
//  std::copy(from_vector, to_vector.begin());
 
    std::cout << "to_vector contains: ";
 
    ranges::copy(to_vector, ranges::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
}

输出

to_vector contains: 1 2 4 5 7 8

[编辑] 参见

将元素范围复制到新位置
(函数模板) [编辑]
以反向顺序复制元素范围
(函数模板) [编辑]
创建反转的范围副本
(函数模板) [编辑]
将一定数量的元素复制到新位置
(函数模板) [编辑]
将元素范围赋值为某个值
(函数模板) [编辑]
复制元素范围,省略满足特定条件的元素
(函数模板) [编辑]