函数模板
<algorithm>

std::partition_copy

template <class InputIterator, class OutputIterator1,          class OutputIterator2, class UnaryPredicate pred>  pair<OutputIterator1,OutputIterator2>    partition_copy (InputIterator first, InputIterator last,                    OutputIterator1 result_true, OutputIterator2 result_false,                    UnaryPredicate pred);
将范围划分为两部分
将范围 [first,last)pred 返回 true 的元素复制到 result_true 指向的范围,将 pred 返回 false 的元素复制到 result_false 指向的范围。

此函数模板的行为等同于
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <class InputIterator, class OutputIterator1,
          class OutputIterator2, class UnaryPredicate pred>
  pair<OutputIterator1,OutputIterator2>
    partition_copy (InputIterator first, InputIterator last,
                    OutputIterator1 result_true, OutputIterator2 result_false,
                    UnaryPredicate pred)
{
  while (first!=last) {
    if (pred(*first)) {
      *result_true = *first;
      ++result_true;
    }
    else {
      *result_false = *first;
      ++result_false;
    }
    ++first;
  }
  return std::make_pair (result_true,result_false);
}

参数

first, last
输入迭代器,指向待复制分区的范围的起始和结束位置。使用的范围是 [first,last),它包含 firstlast 之间的所有元素,包括 first 指向的元素,但不包括 last 指向的元素。
result_true
输出迭代器,指向存储 pred 返回 true 的元素的范围的起始位置。
result_false
输出迭代器,指向存储 pred 返回 false 的元素的范围的起始位置。
pred
一元函数,接受 InputIterator 指向的元素作为参数,并返回可转换为 bool 的值。返回值指示该元素应复制到哪个结果范围。
该函数不得修改其参数。
可以是函数指针,也可以是函数对象。

这些范围不应重叠。
Output iterator 类型指向的对象应支持被赋值范围 [first,last) 中元素的值。

返回值

一个 pair,其迭代器分别指向 result_trueresult_false 生成的序列的末尾。

其成员 first 指向 pred 返回 true 的元素序列中最后一个元素之后的位置。
其成员 second 指向 pred 返回 false 的元素序列中最后一个元素之后的位置。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// partition_copy example
#include <iostream>     // std::cout
#include <algorithm>    // std::partition_copy, std::count_if
#include <vector>       // std::vector

bool IsOdd (int i) { return (i%2)==1; }

int main () {
  std::vector<int> foo {1,2,3,4,5,6,7,8,9};
  std::vector<int> odd, even;

  // resize vectors to proper size:
  unsigned n = std::count_if (foo.begin(), foo.end(), IsOdd);
  odd.resize(n); even.resize(foo.size()-n);

  // partition:
  std::partition_copy (foo.begin(), foo.end(), odd.begin(), even.begin(), IsOdd);

  // print contents:
  std::cout << "odd: ";  for (int& x:odd)  std::cout << ' ' << x; std::cout << '\n';
  std::cout << "even: "; for (int& x:even) std::cout << ' ' << x; std::cout << '\n';

  return 0;
}

输出
odd: 1 3 5 7 9
even: 2 4 6 8


复杂度

线性复杂度,复杂度为 firstlast 之间 距离的线性复杂度:调用 pred 并为每个元素执行一次赋值。

数据竞争

范围 [first,last) 中的对象被访问(每个访问一次)。
result_trueresult_false 所指向的范围中的对象,直到迭代器指向的元素之前的部分会被修改(每个修改一次)。

异常

如果 pred、元素赋值或迭代器操作抛出异常,则此函数也抛出异常。
请注意,无效参数会导致未定义行为

另见