std::transform_exclusive_scan() 算法
- 自 C++20 起
- 自 C++17 起
// (1)
template< class InputIt, class OutputIt, class T, class BinaryOperation, class UnaryOperation >
constexpr OutputIt transform_exclusive_scan( InputIt first, InputIt last, OutputIt d_first, T init,
BinaryOperation binary_op, UnaryOperation unary_op );
// (2)
template<
class ExecutionPolicy,
class ForwardIt1,
class ForwardIt2,
class T,
class BinaryOperation,
class UnaryOperation
>
ForwardIt2 transform_exclusive_scan( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
T init, BinaryOperation binary_op, UnaryOperation unary_op );
// (1)
template< class InputIt, class OutputIt, class T, class BinaryOperation, class UnaryOperation >
OutputIt transform_exclusive_scan( InputIt first, InputIt last, OutputIt d_first, T init,
BinaryOperation binary_op, UnaryOperation unary_op );
// (2)
template<
class ExecutionPolicy,
class ForwardIt1,
class ForwardIt2,
class T,
class BinaryOperation,
class UnaryOperation
>
ForwardIt2 transform_exclusive_scan( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
T init, BinaryOperation binary_op, UnaryOperation unary_op );
使用 unary_op
转换范围 [first
; last
) 中的每个元素,然后使用 binary_op
对结果范围执行排他性前缀和操作,以 init
作为初始值,并将结果写入从 d_first
开始的范围。
"exclusive" 意味着第 i 个输入元素不包含在第 i 个和中。
求和操作可以按任意顺序执行,如果 binary_op
不具有结合性,则行为不确定。
形式上,通过 [d_first
; d_first + (last - first
)) 中的每个迭代器 i
赋值 init
、unary_op(*j)
... 对于 [first
; first + (i - d_first
)) 中的每个 j
,通过 binary_op
计算的广义非交换和的值,
广义和 GSUM(op, a1, ..., aN)
定义如下
-
如果
N = 1
,则为a1
-
如果
N > 1
,则为op(GSUM(op, a1, ..., aK), GSUM(op, aM, ..., aN))
,对于任何K
且1 < K + 1 = M ≤ N
-
(4 - 6) 与 (1 - 3) 相同,但根据策略执行。
重载决议这些重载只有在
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>
为true
时才参与重载决议。 (C++20 之前)std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>
为true
时才参与重载决议。 (C++20 起)
行为未定义
如果unary_op
和 binary_op
使迭代器(包括 end 迭代器)或子范围无效,或者修改范围 [first
; last
) 或 [d_first
; d_first + (last - first
)) 中的元素。参数
first last | 要应用算法的元素范围。 |
d_first | 目标范围的开头,可能等于 |
init | 广义和的初始值。 |
policy | 要使用的执行策略。有关详细信息,请参阅执行策略。 |
exclusive_scan | 一元函数对象,将应用于输入范围的每个元素。返回类型必须可作为 |
transform | 二元函数对象,将应用于 |
类型要求
InputIt | LegacyInputIterator |
OutputIt | LegacyOutputIterator |
ForwardIt1 ForwardIt2 | LegacyForwardIterator |
T | MoveConstructible |
以下表达式必须可转换为 T
binary_op(init, unary_op(*first))
binary_op(init, init)
binary_op(unary_op(*first), unary_op(*first))
返回值
指向已写入的最后一个元素之后的元素的迭代器。
复杂度
binary_op
和 unary_op
各应用 O(last - first) 次。
异常
带有模板参数 ExecutionPolicy
的重载报告错误如下
- 如果作为算法一部分调用的函数执行抛出异常,并且
ExecutionPolicy
是标准策略之一,则调用std::terminate
。对于任何其他ExecutionPolicy
,行为是实现定义的. - 如果算法未能分配内存,则抛出
std::bad_alloc
。
备注
unary_op
不应用于 init。
示例
#include <functional>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
int main()
{
std::vector data {3, 1, 4, 1, 5, 9, 2, 6};
auto times_10 = [](int x) { return x * 10; };
std::cout << "10 times exclusive sum: ";
std::transform_exclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "),
0, std::plus<int>{}, times_10);
std::cout << "\n10 times inclusive sum: ";
std::transform_inclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "),
std::plus<int>{}, times_10);
}
10 times exclusive sum: 0 30 40 80 90 140 230 250
10 times inclusive sum: 30 40 80 90 140 230 250 310