std::transform_inclusive_scan
来自cppreference.com
| 在标头 <numeric> 定义
|
||
| |
(1) | (C++17 起) (C++20 起为 constexpr) |
| |
(2) | (C++17 起) |
| |
(3) | (C++17 起) (C++20 起为 constexpr) |
| |
(4) | (C++17 起) |
1) 用
op 计算包含性前缀和。 对于
[0, std::distance(first, last)) 中的所有整数 i,按顺序进行以下操作:
- 创建一个序列,它按顺序包含依次将
[first,iter)中的所有元素通过unary_op变换得到的值,其中iter是first的下i个迭代器。 - 计算该序列在
binary_op下的广义非交换和。 - 将计算结果赋给
*dest,其中dest是d_first的下i个迭代器。
3) 同 (1),但创建的每个序列以
init 开始,然后按顺序后随 [first, iter] 中的所有元素。2,4) 同 (1,3),但按照
policy 执行。 这些重载只有在满足以下所有条件时才会参与重载决议:
|
|
(C++20 前) |
|
|
(C++20 起) |
一个元素序列在二元运算 binary_op 上的广义非交换和 定义如下:
- 如果序列只有一个元素,那么和就是该元素的值。
- 否则,依次进行以下操作:
- 从序列中选择两个相邻元素
elem1和elem2。 - 计算
binary_op(elem1, elem2),并将序列中的这两个元素替换成计算结果。 - 重复以上两步,直到组里只剩一个元素。
如果 binary_op 不可结合(例如浮点加法),那么结果不确定。
对于重载 (1,2),如果 binary_op(unary_op(*first), unary_op(*first)) 不可转换到 decltype(first) 的值类型,那么程序非良构。
对于重载 (3,4),如果以下任何值不可转换到 T,那么程序非良构:
binary_op(init, init)binary_op(init, unary_op(*first))binary_op(unary_op(*first), unary_op(*first))
- 如果满足以下任意条件,那么行为未定义:
- 对于重载 (1,2),
decltype(first)的值类型不可移动构造 (MoveConstructible) 。 - 对于重载 (3,4),
T不可移动构造 (MoveConstructible) 。 unary_op或binary_op会修改[first,last)的元素。unary_op或binary_op会使[first,last]中的迭代器或子范围失效。
- 对于重载 (1,2),
参数
| first, last | - | 要求和的元素范围的迭代器对 |
| d_first | - | 目标范围起始;可以等于 first
|
| policy | - | 所用的执行策略 |
| init | - | 初值 |
| unary_op | - | 一元函数对象,将要被应用到输入范围中的每个元素。返回类型必须可接受为 binary_op 的输入。
|
| binary_op | - | 二元函数对象,将应用于 unary_op 的结果、其他 binary_op 的结果,还有 init,若提供它。
|
| 类型要求 | ||
-InputIt 必须满足老式输入迭代器 (LegacyInputIterator) 。
| ||
-OutputIt 必须满足老式输出迭代器 (LegacyOutputIterator) 。
| ||
-ForwardIt1, ForwardIt2 必须满足老式向前迭代器 (LegacyForwardIterator) 。
| ||
返回值
指向最后被写入元素后一位置的迭代器。
复杂度
给定 N 为 std::distance(first, last):
1-4) 分别应用 O(N) 次
unary_op 和 binary_op。异常
拥有名为 ExecutionPolicy 的模板形参的重载按下列方式报告错误:
- 如果作为算法一部分调用的函数的执行抛出异常,且
ExecutionPolicy是标准策略之一,那么调用 std::terminate。对于任何其他ExecutionPolicy,行为由实现定义。 - 如果算法无法分配内存,那么抛出 std::bad_alloc。
注解
不会对 init 应用 unary_op。
与 std::transform_exclusive_scan 不同,参数 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);
std::cout << '\n';
}
输出:
10 times exclusive sum: 0 30 40 80 90 140 230 250
10 times inclusive sum: 30 40 80 90 140 230 250 310
