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

< cpp‎ | experimental‎ | ranges
 
 
技术规范
文件系统库 (文件系统 TS)
库基础 (库基础 TS)
库基础 2 (库基础 TS v2)
库基础 3 (库基础 TS v3)
并行扩展 (并行 TS)
并行扩展 2 (并行 TS v2)
并发扩展 (并发 TS)
概念 (概念 TS)
范围 (范围 TS)
数学特殊函数 (特殊函数 TR)
 
 
 
template < ranges::InputIterator I, ranges::Sentinel<I> S,

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

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

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

  copy(Rng&& rng, O result);
(2) (范围 TS)
template < ranges::InputIterator I, ranges::Sentinel<I> S,

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

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

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

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

复制源范围( [first,last)rng )中的元素到始于 result 的目标范围中,从源范围的首元素开始,后续到末元素。

1) 复制范围 [first, last) 中的所有元素。对每个非负整数 n < (last - first) 进行 *(result + n) = *(first + n) 。若 result 在范围 [first, last) 内则行为未定义。此情况下可用 ranges::copy_backward 代替。
2)(1) ,但以 rng 为源范围,如同用 ranges::copy(ranges::begin(rng), ranges::end(rng), result); ,除了不可复制 result
3) 仅复制应用谓词 pred 到投影 proj 所投影的元素值时,对其返回 true 的元素。保持复制后的元素顺序。若源与目标范围重叠则行为未定义。
4)(3) ,但以 rng 为源范围,如同用 ranges::copy_if(ranges::begin(rng), ranges::end(rng), result, pred, proj); ,除了不可复制 resultpredproj

参数

first, last - 要复制的元素范围
rng - 要复制的元素范围
result - 目标范围的起始
pred - 要应用到投影后元素的谓词
proj - 要应用到元素的投影

返回值

含有以下二个成员的 tagged_pair 对象:

  • 第一成员有标签 tag::in ,为源范围的尾后迭代器(即比较等于哨位 lastI 类型迭代器)。
  • 第二成员有标签 tag::out ,为结果范围的尾后迭代器。

复杂度

1) 准确赋值 ranges::distance(first, last) 次。
2) 准确赋值 ranges::distance(rng) 次。
3) 准确应用 ranges::distance(first, last) 次对应的投影和谓词。
3) 准确应用 ranges::distance(rng) 次对应的投影和谓词。

可能的实现

版本一
template <ranges::InputIterator I, ranges::Sentinel<I> S, ranges::WeaklyIncrementable O>
  requires ranges::IndirectlyCopyable<I, O>()
ranges::tagged_pair<ranges::tag::in(I), ranges::tag::out(O)>
  copy(I first, S last, O result)
{
    for (; first != last; ++first, (void)++result)
        *result = *first;
    return {first, result};
}
版本二
template <ranges::InputRange Rng, ranges::WeaklyIncrementable O>
  requires ranges::IndirectlyCopyable<ranges::iterator_t<Rng>, O>()
ranges::tagged_pair<ranges::tag::in(ranges::safe_iterator_t<Rng>), ranges::tag::out(O)>
  copy(Rng&& rng, O result)
{
   return ranges::copy(ranges::begin(rng), ranges::end(rng), result);
}
版本三
template <ranges::InputIterator I, ranges::Sentinel<I> S, ranges::WeaklyIncrementable O,
          class Proj = ranges::identity,
          ranges::IndirectUnaryPredicate<ranges::projected<I, Proj>> Pred>
  requires ranges::IndirectlyCopyable<I, O>()
ranges::tagged_pair<ranges::tag::in(I), ranges::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 <ranges::InputRange Rng, ranges::WeaklyIncrementable O,
          class Proj = ranges::identity,
          ranges::IndirectUnaryPredicate<
              ranges::projected<ranges::iterator_t<Rng>, Proj>> Pred>
  requires ranges::IndirectlyCopyable<ranges::iterator_t<Rng>, O>()
ranges::tagged_pair<ranges::tag::in(ranges::safe_iterator_t<Rng>), ranges::tag::out(O)>
  copy_if(Rng&& rng, O result, Pred pred, Proj proj = Proj{})
{
   return ranges::copy_if(ranges::begin(rng), ranges::end(rng), result, pred, proj);
}

示例

下列代码用 copy 复制一个 vector 的内容给另一个,并显示结果 vector

#include <experimental/ranges/algorithm>
#include <iostream>
#include <vector>
#include <experimental/ranges/iterator>
#include <numeric>
 
int main()
{
    // 参阅 https://www.apiref.com/cpp-zh/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;
                    });
// 或替用的
//  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

参阅

将某一范围的元素复制到一个新的位置
(函数模板)
按从后往前的顺序复制一个范围内的元素
(函数模板)
创建一个范围的逆向副本
(函数模板)
将一定数目的元素复制到一个新的位置
(函数模板)
将一个特定值赋值给一个元素范围
(函数模板)
复制元素范围,忽略满足特定判别标准的元素
(函数模板)