跳到主要内容

std::transform_inclusive_scan() 算法

// (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 );

使用 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_opbinary_op 使迭代器(包括 end 迭代器)或子范围失效,或修改范围 [first; last) 或 [d_first; d_first + (last - first)) 中的元素。

参数

first
last

要应用算法的元素范围。

d_first

目标范围的开头,可以等于 first

init

广义和的初始值。

policy

要使用的执行策略。有关详细信息,请参阅执行策略

inclusive_scan

应用于输入范围每个元素的单目函数对象。返回类型必须可作为 binary_op 的输入。

transform

应用于 unary_op 结果、其他 binary_op 结果和 init 的二元函数对象

类型要求

InputItLegacyInputIterator
OutputItLegacyOutputIterator
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_opunary_op 各应用 O(last - first) 次。

异常

带有模板参数 ExecutionPolicy 的重载报告错误如下

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

备注

unary_op 不应用于 init

参数 init 出现在最后,这与 std::transform_exclusive_scan 不同,因为它对于此函数是可选的。

示例

Main.cpp
#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
本文源自此 CppReference 页面。它可能经过了修改以进行改进或适应编辑偏好。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。

std::transform_inclusive_scan() 算法

// (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 );

使用 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_opbinary_op 使迭代器(包括 end 迭代器)或子范围失效,或修改范围 [first; last) 或 [d_first; d_first + (last - first)) 中的元素。

参数

first
last

要应用算法的元素范围。

d_first

目标范围的开头,可以等于 first

init

广义和的初始值。

policy

要使用的执行策略。有关详细信息,请参阅执行策略

inclusive_scan

应用于输入范围每个元素的单目函数对象。返回类型必须可作为 binary_op 的输入。

transform

应用于 unary_op 结果、其他 binary_op 结果和 init 的二元函数对象

类型要求

InputItLegacyInputIterator
OutputItLegacyOutputIterator
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_opunary_op 各应用 O(last - first) 次。

异常

带有模板参数 ExecutionPolicy 的重载报告错误如下

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

备注

unary_op 不应用于 init

参数 init 出现在最后,这与 std::transform_exclusive_scan 不同,因为它对于此函数是可选的。

示例

Main.cpp
#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
本文源自此 CppReference 页面。它可能经过了修改以进行改进或适应编辑偏好。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。