Namespaces
Variants

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

From cppreference.net
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) (ranges 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) (ranges 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) (ranges 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) (ranges TS)

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

1) 复制范围 [ first , last ) 内的所有元素。对于每个非负整数 n < (last - first) ,执行 * ( result + n ) = * ( first + n ) 。若 result 位于范围 [ first , last ) 内则行为未定义。此种情况下可改用 ranges::copy_backward
2) (1) 相同,但使用 r 作为源范围,如同通过 ranges:: copy ( ranges:: begin ( r ) , ranges:: end ( r ) , result ) ; 实现,不同之处在于 result 可能不会被复制。
3) 仅复制那些当投影函数 proj 对元素值进行投影后,谓词 pred 返回 true 的元素。被复制元素的顺序将保持不变。若源范围与目标范围重叠,则行为未定义。
4) (3) 相同,但使用 r 作为源范围,如同通过 ranges:: copy_if ( ranges:: begin ( r ) , ranges:: end ( r ) , result, pred, proj ) ; 执行,但 result pred proj 可能不会被复制。

尽管存在上述声明,算法声明的实际模板参数数量和顺序是未指定的。因此,如果在调用算法时使用了显式模板参数,程序很可能不具备可移植性。

目录

参数

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://en.cppreference.net/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

参见

将元素范围复制到新位置
(函数模板)
按逆序复制元素范围
(函数模板)
创建反转范围的副本
(函数模板)
复制指定数量的元素到新位置
(函数模板)
为元素范围赋予特定值
(函数模板)
复制元素范围并忽略满足特定条件的元素
(函数模板)