The Wayback Machine - https://web.archive.org/web/20180513212540/http://zh.cppreference.com:80/w/cpp/algorithm/transform_reduce

std::transform_reduce

来自cppreference.com
< cpp‎ | algorithm
 
 
算法库
执行策略 (C++17)
不修改序列的操作
(C++11)
(C++11)
(C++11)
(C++17)
修改序列的操作
未初始化存储上的操作
划分操作
排序操作
二分搜索操作
集合操作(在已排序范围上)
堆操作
(C++11)
最小/最大操作
(C++11)
(C++17)
排列
数值运算
(C++17)
transform_reduce
(C++17)
C 库
 
定义于头文件 <numeric>
template<class InputIt1, class InputIt2, class T>
T transform_reduce(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init);
(1) (C++17 起)
template<class InputIt1, class InputIt2, class T, class BinaryOp1, class BinaryOp2>

T transform_reduce(InputIt1 first1, InputIt1 last1, InputIt2 first2,

                   T init, BinaryOp1 binary_op1, BinaryOp2 binary_op2);
(2) (C++17 起)
template<class InputIt, class T, class BinaryOp, class UnaryOp>

T transform_reduce(InputIt first, InputIt last,

                   T init, BinaryOp binop, UnaryOp unary_op);
(3) (C++17 起)
template<class ExecutionPolicy,

         class ForwardIt1, class ForwardIt2, class T>
T transform_reduce(ExecutionPolicy&& policy,

                   ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, T init);
(4) (C++17 起)
template<class ExecutionPolicy,

         class ForwardIt1, class ForwardIt2, class T, class BinaryOp1, class BinaryOp2>
T transform_reduce(ExecutionPolicy&& policy,
                   ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2,

                   T init, BinaryOp1 binary_op1, BinaryOp2 binary_op2);
(5) (C++17 起)
template<class ExecutionPolicy,

         class ForwardIt, class T, class BinaryOp, class UnaryOp>
T transform_reduce(ExecutionPolicy&& policy,
                   ForwardIt first, ForwardIt last,

                   T init, BinaryOp binary_op, UnaryOp unary_op);
(6) (C++17 起)
1) 等价于 transform_reduce(first1, last1, first2, init, std::plus<>(), std::multiplies<>()); ,默认的 std::inner_product 的等效并行版本
2) 应用 binary_op2 到来自范围 [first; last) 和始于 first2 的范围的每对元素,并在 binary_op1 上与初始值 init 一同规约结果(可以以未指定行为重排聚合)
3) 应用 unary_op 到范围 [first; last) 中的每个元素,并在 binary_op 上与初始值 init 一同规约结果(可以以未指定行为重排聚合)。
4-6)(1-3) ,但按照 policy 执行。此重载仅若 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> 为 true才参与重载决议

binary_op/binary_op2 为非交换或非结合则行为不确定。

unary_opbinary_opbinary_op1binary_op2 修改输入范围中的任何元素或非法化范围中的任何迭代器,含尾迭代器,则行为未定义。

目录

[编辑]参数

first, last - 要应用算法的元素范围
init - 广义和的初始值
policy - 使用的执行策略,细节见执行策略
unary_op - 将应用于输入范围的每个元素的一元函数对象 (FunctionObject) 。返回类型必须可为 binary_op 的输入所接受
binary_op - 将以未指定顺序应用于 unary_op 的结果、其他 binary_op 的结果和 init 的二元函数对象 (FunctionObject) 。
类型要求
-
为使用重载 (3,6) , T 必须满足 MoveConstructible 的要求。且表达式 binary_op(init, unary_op(*first))binary_op(unary_op(*first), init)binary_op(init, init)binary_op(unary_op(*first), unary_op(*first)) 的结果必须可转换为 T
-
为使用重载 (2,5) , T 必须满足 MoveConstructible 的要求。且表达式 binary_op1(init, binary_op2(*first1, *first2))binary_op1(binary_op2(*first1, *first2), init)binary_op1(init, init)binary_op1(binary_op2(*first1, *first2), binary_op2(*first1, *first2)) 的结果必须可转换为 T
-
InputIt 必须满足 InputIterator 的要求。
-
ForwardIt 必须满足 ForwardIterator 的要求。

[编辑]返回值

2)initbinary_op2(*first,*first2)binary_op2(*(first+1),*(first2+1)) ……在 binary_op1 上的广义和
3)initunary_op(*first)unary_op(*(first+1)) …… unary_op(*(last-1))binary_op 上的广义和,

其中广义和 GSUM(op, a
1
, ..., a
N
)
定义如下:

  • N=1 ,则为 a
    1
  • N > 1 ,则为 op(GSUM(op, b
    1
    , ..., b
    K
    ), GSUM(op, b
    M
    , ..., b
    N
    ))
    ,其中
  • b
    1
    , ..., b
    N
    可以是 a1, ..., aN 的任意重排,若
  • 1 < K+1 = M ≤ N

换言之, unary_op 或 binary_op1 的结果能以任意顺序组合排列。

[编辑]复杂度

1,2,4,5) 各使用 O(last1 - first1)binary_op1binary_op2
3,6) 各使用 O(last - first)unary_opbinary_op

[编辑]异常

拥有名为 ExecutionPolicy 的模板参数的重载按下列方式报告错误:

  • 若作为算法一部分调用的函数的执行抛出异常,且 ExecutionPolicy 是三个标准策略之一,则调用 std::terminate 。对于任何其他 ExecutionPolicy ,行为是实现定义的。
  • 若算法无法分配内存,则抛出 std::bad_alloc

[编辑]注意

在一元-二元重载 (3,6) 中, unary_op 不应用于 init

first == lastfirst1 == last1 ,则返回不修改的 init

[编辑]示例

transform_reduce 能用于并行化的 std::inner_product

#include <vector>#include <functional>#include <iostream>#include <numeric>#include <execution>   int main(){std::vector<double> xvalues(10007, 1.0), yvalues(10007, 1.0);   double result = std::transform_reduce(std::execution::par, xvalues.begin(), xvalues.end(), yvalues.begin(), 0.0);std::cout<< result <<'\n';}

输出:

10007

[编辑]参阅

计算区间内元素的和
(函数模板)[编辑]
将一个函数应用于某一范围的元素
(函数模板)[编辑]
(C++17)
类似 std::accumulate ,除了以乱序
(函数模板)[编辑]
close