std::transform_inclusive_scan() 算法
- 自 C++20 起
- 自 C++17 起
// (1)
template< class InputIt, class OutputIt, class BinaryOperation, class UnaryOperation >
constexpr OutputIt transform_inclusive_scan( InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op,
UnaryOperation unary_op );
// (2) (3)
template< class InputIt, class OutputIt, class BinaryOperation, class UnaryOperation, class T >
constexpr OutputIt transform_inclusive_scan( InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op,
UnaryOperation unary_op, T init );
// (3) (2)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryOperation, class UnaryOperation >
ForwardIt2 transform_inclusive_scan( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op, UnaryOperation unary_op );
// (4)
template<
class ExecutionPolicy,
class ForwardIt1,
class ForwardIt2,
class BinaryOperation,
class UnaryOperation,
class T
>
ForwardIt2 transform_inclusive_scan( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op, UnaryOperation unary_op, T init );
// (1)
template< class InputIt, class OutputIt, class BinaryOperation, class UnaryOperation >
OutputIt transform_inclusive_scan( InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op,
UnaryOperation unary_op );
// (2) (3)
template< class InputIt, class OutputIt, class BinaryOperation, class UnaryOperation, class T >
OutputIt transform_inclusive_scan( InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op,
UnaryOperation unary_op, T init );
// (3) (2)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryOperation, class UnaryOperation >
ForwardIt2 transform_inclusive_scan( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op, UnaryOperation unary_op );
// (4)
template<
class ExecutionPolicy,
class ForwardIt1,
class ForwardIt2,
class BinaryOperation,
class UnaryOperation,
class T
>
ForwardIt2 transform_inclusive_scan( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op, UnaryOperation unary_op, T init );
使用 unary_op
转换范围 [first
; last
) 中的每个元素,然后使用 binary_op
在结果范围内计算一个包含性前缀和操作,可选择以 init
作为初始值,并将结果写入从 d_first
开始的范围。
"包含性"意味着第 i 个输入元素包含在第 i 个和中。
换句话说,求和操作可以以任意顺序执行,如果 binary_op
不满足结合律,则行为是不确定的。
形式上,对于 [d_first
; d_first + (last - first
)) 中的每个迭代器 i
,赋值为广义非交换和的值:
- (1, 3)
unary_op(*j)
... 对于 [first
;first + (i - d_first + 1
)) 中使用binary_op
的每个j
, - (2, 4)
init
,unary_op(*j)
... 对于 [first
;first + (i - d_first + 1
)) 中使用binary_op
的每个j
,
广义和 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 | 要使用的执行策略。有关详细信息,请参阅执行策略。 |
inclusive_scan | 应用于输入范围每个元素的单目函数对象。返回类型必须可作为 |
transform | 应用于 |
类型要求
InputIt | LegacyInputIterator |
OutputIt | LegacyOutputIterator |
ForwardIt1 ForwardIt2 | LegacyForwardIterator |
T | 可移动构造 (MoveConstructible) |
-
如果未提供
init
,则decltype(first)
的值类型必须是MoveConstructible
。以下表达式必须可转换为decltype(first)
的值类型binary_op(unary_op(*first), unary_op(*first))
-
T
(如果提供了init
)必须满足MoveConstructible
的要求。以下表达式必须可转换为decltype(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
。
参数 init
出现在最后,这与 std::transform_exclusive_scan
不同,因为它对于此函数是可选的。
示例
#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 inclusive sum: 0 30 40 80 90 140 230 250
10 times inclusive sum: 30 40 80 90 140 230 250 310