This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofResolved status.
ForwardIterator should only mean forward iteratorSection: 26.11[specialized.algorithms]Status:ResolvedSubmitter: Casey CarterOpened: 2018-09-06Last modified: 2020-05-02
Priority:3
View otheractive issues in [specialized.algorithms].
View all otherissues in [specialized.algorithms].
View all issues withResolved status.
Discussion:
26.11[specialized.algorithms] para 1.2 describes how the specializedalgorithms with a template parameter namedForwardIterator imposerequirements on the type passed as argument for that parameter: it must meettheCpp17ForwardIterator requirements, which is consistent withhow the rest of the Library uses the template parameter nameForwardIterator, and many of the required operations on that type mustnot throw exceptions, which isnot consistent with how the rest of theLibrary uses that name.
To avoid confusion and keep the meaning of requirements imposed by templateparameter names crisp, the specialized memory algorithms should use a differenttemplate parameter name for this different set of requirements.
Note that the proposed change has no normative effect; it's simply aclarification of the existing wording.
[2018-09 Reflector prioritization]
Set Priority to 3
Previous resolution [SUPERSEDED]:
This wording is relative toN4762.
Modify 20.2.2[memory.syn] as indicated:
[…]// 26.11[specialized.algorithms], specialized algorithmstemplate<class T> constexpr T* addressof(T& r) noexcept;template<class T> const T* addressof(const T&&) = delete;template<classNoThrowForwardIterator> void uninitialized_default_construct(NoThrowForwardIterator first,NoThrowForwardIterator last);template<class ExecutionPolicy, classNoThrowForwardIterator> void uninitialized_default_construct(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads]NoThrowForwardIterator first,NoThrowForwardIterator last);template<classNoThrowForwardIterator, class Size>NoThrowForwardIterator uninitialized_default_construct_n(NoThrowForwardIterator first, Size n);template<class ExecutionPolicy, classNoThrowForwardIterator, class Size>NoThrowForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads]NoThrowForwardIterator first, Size n);template<classNoThrowForwardIterator> void uninitialized_value_construct(NoThrowForwardIterator first,NoThrowForwardIterator last);template<class ExecutionPolicy, classNoThrowForwardIterator> void uninitialized_value_construct(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads]NoThrowForwardIterator first,NoThrowForwardIterator last);template<classNoThrowForwardIterator, class Size>NoThrowForwardIterator uninitialized_value_construct_n(NoThrowForwardIterator first, Size n);template<class ExecutionPolicy, classNoThrowForwardIterator, class Size>NoThrowForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads]NoThrowForwardIterator first, Size n);template<class InputIterator, classNoThrowForwardIterator>NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last,NoThrowForwardIterator result);template<class ExecutionPolicy, class InputIterator, classNoThrowForwardIterator>NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads] InputIterator first, InputIterator last,NoThrowForwardIterator result);template<class InputIterator, class Size, classNoThrowForwardIterator>NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n,NoThrowForwardIterator result);template<class ExecutionPolicy, class InputIterator, class Size, classNoThrowForwardIterator>NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads] InputIterator first, Size n,NoThrowForwardIterator result);template<class InputIterator, classNoThrowForwardIterator>NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last,NoThrowForwardIterator result);template<class ExecutionPolicy, class InputIterator, classNoThrowForwardIterator>NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads] InputIterator first, InputIterator last,NoThrowForwardIterator result);template<class InputIterator, class Size, classNoThrowForwardIterator> pair<InputIterator,NoThrowForwardIterator> uninitialized_move_n(InputIterator first, Size n,NoThrowForwardIterator result);template<class ExecutionPolicy, class InputIterator, class Size, classNoThrowForwardIterator> pair<InputIterator,NoThrowForwardIterator> uninitialized_move_n(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads] InputIterator first, Size n,NoThrowForwardIterator result);template<classNoThrowForwardIterator, class T> void uninitialized_fill(NoThrowForwardIterator first,NoThrowForwardIterator last, const T& x);template<class ExecutionPolicy, classNoThrowForwardIterator, class T> void uninitialized_fill(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads]NoThrowForwardIterator first,NoThrowForwardIterator last, const T& x);template<classNoThrowForwardIterator, class Size, class T>NoThrowForwardIterator uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x);template<class ExecutionPolicy, classNoThrowForwardIterator, class Size, class T>NoThrowForwardIterator uninitialized_fill_n(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads]NoThrowForwardIterator first, Size n, const T& x);template<class T> void destroy_at(T* location);template<classNoThrowForwardIterator> void destroy(NoThrowForwardIterator first,NoThrowForwardIterator last);template<class ExecutionPolicy, classNoThrowForwardIterator> void destroy(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads]NoThrowForwardIterator first,NoThrowForwardIterator last);template<classNoThrowForwardIterator, class Size>NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, Size n);template<class ExecutionPolicy, classNoThrowForwardIterator, class Size>NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // see 26.3.5[algorithms.parallel.overloads]NoThrowForwardIterator first, Size n);// 20.3.1[unique.ptr], class template unique_ptr[…]Modify 26.11[specialized.algorithms] as indicated:
[…]
(1.2) — If an algorithm's template parameter is named
NoThrowForwardIterator, the template argument shall satisfytheCpp17ForwardIteratorrequirements(24.3.5.5[forward.iterators]), and is required to have the property thatno exceptions are thrown from increment, assignment, comparison, or indirectionthrough valid iterators.[…]
Modify the declarations of the specialized algorithms in the remainder of26.11[specialized.algorithms] to agree with the proposed changes to20.2.2[memory.syn] above.
[2020-05-02; Reflector discussions]
The issue has been resolved by acceptingP1963R0in Prague 2020.
Proposed resolution:
Resolved byP1963R0.