This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.
ForwardIterator
should only mean forward iteratorSection: 26.11 [specialized.algorithms] Status: Resolved Submitter: Casey Carter Opened: 2018-09-06 Last modified: 2020-05-02
Priority: 3
View other active issues in [specialized.algorithms].
View all other issues in [specialized.algorithms].
View all issues with Resolved status.
Discussion:
26.11 [specialized.algorithms] para 1.2 describes how the specialized
algorithms with a template parameter named ForwardIterator
impose
requirements on the type passed as argument for that parameter: it must meet
the Cpp17ForwardIterator
requirements, which is consistent with
how the rest of the Library uses the template parameter name
ForwardIterator
, and many of the required operations on that type must
not throw exceptions, which is not consistent with how the rest of the
Library uses that name.
To avoid confusion and keep the meaning of requirements imposed by template parameter names crisp, the specialized memory algorithms should use a different template parameter name for this different set of requirements.
Note that the proposed change has no normative effect; it's simply a clarification of the existing wording.
[2018-09 Reflector prioritization]
Set Priority to 3
Previous resolution [SUPERSEDED]:
This wording is relative to N4762.
Modify 20.2.2 [memory.syn] as indicated:
[…] // 26.11 [specialized.algorithms], specialized algorithms template<class T> constexpr T* addressof(T& r) noexcept; template<class T> const T* addressof(const T&&) = delete; template<class NoThrowForwardIterator> void uninitialized_default_construct(NoThrowForwardIterator first, NoThrowForwardIterator last); template<class ExecutionPolicy, class NoThrowForwardIterator> void uninitialized_default_construct(ExecutionPolicy&& exec, // see 26.3.5 [algorithms.parallel.overloads] NoThrowForwardIterator first, NoThrowForwardIterator last); template<class NoThrowForwardIterator, class Size> NoThrowForwardIterator uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); template<class ExecutionPolicy, class NoThrowForwardIterator, class Size> NoThrowForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, // see 26.3.5 [algorithms.parallel.overloads] NoThrowForwardIterator first, Size n); template<class NoThrowForwardIterator> void uninitialized_value_construct(NoThrowForwardIterator first, NoThrowForwardIterator last); template<class ExecutionPolicy, class NoThrowForwardIterator> void uninitialized_value_construct(ExecutionPolicy&& exec, // see 26.3.5 [algorithms.parallel.overloads] NoThrowForwardIterator first, NoThrowForwardIterator last); template<class NoThrowForwardIterator, class Size> NoThrowForwardIterator uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); template<class ExecutionPolicy, class NoThrowForwardIterator, class Size> NoThrowForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, // see 26.3.5 [algorithms.parallel.overloads] NoThrowForwardIterator first, Size n); template<class InputIterator, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last, NoThrowForwardIterator result); template<class ExecutionPolicy, class InputIterator, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see 26.3.5 [algorithms.parallel.overloads] InputIterator first, InputIterator last, NoThrowForwardIterator result); template<class InputIterator, class Size, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, NoThrowForwardIterator result); template<class ExecutionPolicy, class InputIterator, class Size, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see 26.3.5 [algorithms.parallel.overloads] InputIterator first, Size n, NoThrowForwardIterator result); template<class InputIterator, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last, NoThrowForwardIterator result); template<class ExecutionPolicy, class InputIterator, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see 26.3.5 [algorithms.parallel.overloads] InputIterator first, InputIterator last, NoThrowForwardIterator result); template<class InputIterator, class Size, class NoThrowForwardIterator> pair<InputIterator, NoThrowForwardIterator> uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result); template<class ExecutionPolicy, class InputIterator, class Size, class NoThrowForwardIterator> pair<InputIterator, NoThrowForwardIterator> uninitialized_move_n(ExecutionPolicy&& exec, // see 26.3.5 [algorithms.parallel.overloads] InputIterator first, Size n, NoThrowForwardIterator result); template<class NoThrowForwardIterator, class T> void uninitialized_fill(NoThrowForwardIterator first, NoThrowForwardIterator last, const T& x); template<class ExecutionPolicy, class NoThrowForwardIterator, class T> void uninitialized_fill(ExecutionPolicy&& exec, // see 26.3.5 [algorithms.parallel.overloads] NoThrowForwardIterator first, NoThrowForwardIterator last, const T& x); template<class NoThrowForwardIterator, class Size, class T> NoThrowForwardIterator uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); template<class ExecutionPolicy, class NoThrowForwardIterator, 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<class NoThrowForwardIterator> void destroy(NoThrowForwardIterator first, NoThrowForwardIterator last); template<class ExecutionPolicy, class NoThrowForwardIterator> void destroy(ExecutionPolicy&& exec, // see 26.3.5 [algorithms.parallel.overloads] NoThrowForwardIterator first, NoThrowForwardIterator last); template<class NoThrowForwardIterator, class Size> NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, Size n); template<class ExecutionPolicy, class NoThrowForwardIterator, 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 satisfy theCpp17ForwardIterator
requirements (24.3.5.5 [forward.iterators]), and is required to have the property that no exceptions are thrown from increment, assignment, comparison, or indirection through valid iterators.[…]
Modify the declarations of the specialized algorithms in the remainder of 26.11 [specialized.algorithms] to agree with the proposed changes to 20.2.2 [memory.syn] above.
[2020-05-02; Reflector discussions]
The issue has been resolved by accepting P1963R0 in Prague 2020.
Proposed resolution:
Resolved by P1963R0.