C++ 中的 std::transform_exclusive_scan

2025 年 5 月 24 日 | 4 分钟阅读

一个名为 std::transform_exclusive_scan 的 C++ 假想函数结合了 std::transform 和 std::exclusive_scan 的功能。这个假想函数会在对序列中的每个元素应用一元转换函数后,计算转换后元素的排他性扫描(前缀和)。该函数签名可能会接受扫描的初始值、指向存储结果的目标范围开头的输出迭代器、定义要转换的元素范围的输入迭代器、用于在扫描期间组合元素的二元操作以及应用于输入序列的每个元素的一元操作。

该函数会遍历输入序列,使用一元操作转换每个元素,然后将结果存储在输出范围中。之后,它会使用二元操作组合元素,从原始值开始,并对转换后的元素进行排他性扫描。这样的函数将通过提供一种快速简便的方法来在单个操作中转换和计算序列的前缀和,从而提高 C++ 标准库在数值和数据处理任务中的表达能力和灵活性。

语法

它具有以下语法:

参数

  • first, last: 输入迭代器,用于指定需要扫描和转换的元素集。
  • result: 输出迭代器,用于存储排他性扫描的结果。
  • binary_op: 排他性扫描使用的二元操作。
  • unary_op: 在扫描之前,每个元素都应用一个一元操作。

操作

  • 该函数会将结果存储在从 result 开始的输出范围中,并对输入范围 [first, last] 中的每个元素执行一元操作 unary_op。
  • 之后,它会使用二元操作 binary_op 对转换后的元素执行排他性扫描,从初始值 init 开始。
  • 在输出范围的适当位置,将存储每个扫描步骤的结果。

返回值

  • 该函数可以返回一个迭代器,指向输出范围中写入的最后一个元素之后的元素。

优点

C++ 中 std::transform_exclusive_scan 的几个优点如下:

  1. 方便性: std::transform_exclusive_scan 将提供一种有效的方式,在单个函数调用中执行排他性扫描操作以及转换。它将通过消除单独循环或函数调用的要求来简化和提高代码的可读性。
  2. 效率: std::transform_exclusive_scan 可以通过将转换和扫描合并到单个操作中来优化内存访问模式并减少不必要的中间存储。它可能比单独的转换和扫描操作具有更好的性能。

缺点

C++ 中 std::transform_exclusive_scan 的几个缺点如下:

  1. 复杂性: 将转换和扫描函数组合到单个函数中可能会增加函数接口和实现的复杂性。为了有效地使用该函数,用户需要理解转换和扫描两个方面,这可能会导致混淆或误用。
  2. 灵活性有限: std::transform_exclusive_scan 可能无法处理所有情况,但在大多数排他性扫描遵循转换的情况下会很有帮助。在某些更复杂或专门的使用场景中,用户可能仍然不得不求助于独立的转换和扫描操作。

示例

让我们举一个例子来说明 C++ 中的 std::transform_exclusive_scan 函数。

输出

The 5 times exclusive sum: 0 10 30 75 105 120 150 190 
The 5 times inclusive sum: 10 30 75 105 120 150 190 200   

说明

此 C++ 代码演示了如何将 lambda 表达式和其他标准组件与标准库的 std::transform_exclusive_scan 和 std::transform_inclusive_scan 函数结合使用。

整数序列 {2, 4, 9, 6, 3, 6, 8, 2} 可以在 elements 向量中找到。

为了将整数乘以五,使用 lambda 函数 times_five。

std::transform_exclusive_scan 计算 elements 向量成员的排他性扫描(前缀和)。从初始值 0 开始,对每个元素应用 times_5 转换,然后使用加法累积结果。std::transform_inclusive_scan 计算 elements 向量项的包容性扫描,结果流式传输到 std::cout。它对每个元素执行 times_5 转换,与 std::transform_exclusive_scan 相同,然后累加结果。

但是,当前元素包含在结果中。结果也流式传输到 std::cout。Times_5 转换原始向量的每个元素并相应地累积,在输出中显示排他性扫描和包容性扫描的结果。