**Section:** 27.10.9 [inclusive.scan], 27.10.11 [transform.inclusive.scan] **Status:** C++20
**Submitter:** Jonathan Wakely **Opened:** 2019-06-18 **Last modified:** 2021-02-25 10:48:01 UTC

**Priority: **0

**View all issues with** C++20 status.

**Discussion:**

after applying P0574R1 to the working draft,
27.10.11 [transform.inclusive.scan] bullet 1.1 says "If `init` is provided, […];
otherwise, `ForwardIterator1`'s value type shall be […]."
27.10.11 [transform.inclusive.scan] bullet 1.2 says "If `init` is provided, […];
otherwise, […] shall be convertible to `ForwardIterator1`'s value type."

For the first overload `init` is not provided, but there is no `ForwardIterator1`, so
these requirements cannot be met. The requirements for the first overload need to be stated in terms
of `InputIterator`'s value type, not `ForwardIterator1`'s value type.

The same problem exists in 27.10.9 [inclusive.scan]. 27.10.12 [adjacent.difference] solves
this problem by saying "Let `T` be the value type of `decltype(first)`".

*[2019-07 Issue Prioritization]*

Status to Tentatively Ready after five positive votes on the reflector.

**Proposed resolution:**

This wording is relative to N4820.

Modify 27.10.9 [inclusive.scan] as indicated:

template<class InputIterator, class OutputIterator, class BinaryOperation> OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation> ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op); template<class InputIterator, class OutputIterator, class BinaryOperation, class T> OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, T init); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation, class T> ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, T init);

-?- Let

`U`be the value type of`decltype(first)`.-3-

*Requires:*(3.1) — If

`init`is provided,`T`shall be*Cpp17MoveConstructible*(Table 26); otherwise,`ForwardIterator1`'s value type`U`shall be*Cpp17MoveConstructible*.(3.2) — If

`init`is provided, all of`binary_op(init, init)`,`binary_op(init, *first)`, and`binary_op(*first, *first)`shall be convertible to`T`; otherwise,`binary_op(*first, *first)`shall be convertible to`ForwardIterator1`'s value type`U`.(3.3) —

`binary_op`shall neither invalidate iterators or subranges, nor modify elements in the ranges`[first, last]`or`[result, result + (last - first)]`.

Modify 27.10.11 [transform.inclusive.scan] as indicated:

template<class InputIterator, class OutputIterator, class BinaryOperation, class UnaryOperation> OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, UnaryOperation unary_op); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation, class UnaryOperation> ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op); template<class InputIterator, class OutputIterator, class BinaryOperation, class UnaryOperation, class T> OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, UnaryOperation unary_op, T init); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation, class UnaryOperation, class T> ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op, T init);

-?- Let

`U`be the value type of`decltype(first)`.-1-

*Requires:*(1.1) — If

`init`is provided,`T`shall be*Cpp17MoveConstructible*(Table 26); otherwise,`ForwardIterator1`'s value type`U`shall be*Cpp17MoveConstructible*.(1.2) — If

`init`is provided, all of(1.2.1) —

`binary_op(init, init)`,(1.2.2) —

`binary_op(init, unary_op(*first))`, and(1.2.3) —

`binary_op(unary_op(*first), unary_op(*first))`

shall be convertible to

`T`; otherwise,`binary_op(unary_op(*first), unary_op(*first))`shall be convertible to`ForwardIterator1`'s value type`U`.(1.3) — Neither

`unary_op`nor`binary_op`shall invalidate iterators or subranges, nor modify elements in the ranges`[first, last]`or`[result, result + (last - first)]`.