Created on 2024-10-20.00:00:00 last changed 1 month ago
Proposed resolution:
This wording is relative to N4993.
Modify [alg.min.max] as indicated:
template<class T> constexpr const T& min(const T& a, const T& b); template<class T, class Compare> constexpr const T& min(const T& a, const T& b, Compare comp); template<class T, class Proj = identity, indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> constexpr const T& ranges::min(const T& a, const T& b, Comp comp = {}, Proj proj = {});
-?- Let comp be less{} and proj be identity{} for the overloads with no parameters by those names.
-1- Preconditions: For the first form, T meets the Cpp17LessThanComparable requirements (Table [tab:cpp17.lessthancomparable]).
-2- Returns: The smaller value.
Returns the first argument
when the arguments are equivalent.
Effects: Equivalent to:
return invoke(comp, invoke(proj, b), invoke(proj, a)) ? b : a;
-3- Complexity: Exactly one comparison
and two applications of the projection, if any.
-4- Remarks: An invocation may explicitly specify an argument for the template parameter T of the overloads in namespace std.
template<class T> constexpr T min(initializer_list<T> r); template<class T, class Compare> constexpr T min(initializer_list<T> r, Compare comp); template<copyable T, class Proj = identity, indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> constexpr T ranges::min(initializer_list<T> r, Comp comp = {}, Proj proj = {}); template<input_range R, class Proj = identity, indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*> constexpr range_value_t<R> ranges::min(R&& r, Comp comp = {}, Proj proj = {});
-?- Let comp be less{} and proj be identity{} for the overloads with no parameters by those names.
-5- Preconditions: ranges::distance(r) > 0. For the overloads in namespace std, T meets the Cpp17CopyConstructible requirements (Table [tab:cpp17.copyconstructible]). For the first form, T meets the Cpp17LessThanComparable requirements (Table [tab:cpp17.lessthancomparable]).
-6- Returns: The smallest value in the input range.
Returns a copy of the leftmost element
when several elements are equivalent to the smallest.
Returns a copy of the leftmost element e
in the input range r for which
bool(invoke(comp, invoke(proj, x), invoke(proj, e)))
is false for all elements x in r.
-7- Complexity: Exactly ranges::distance(r) - 1 comparisons and
twice as many applications of the projection, if any.
-8- Remarks: An invocation may explicitly specify an argument for the template parameter T of the overloads in namespace std.
template<class T> constexpr const T& max(const T& a, const T& b); template<class T, class Compare> constexpr const T& max(const T& a, const T& b, Compare comp); template<class T, class Proj = identity, indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> constexpr const T& ranges::max(const T& a, const T& b, Comp comp = {}, Proj proj = {});
-?- Let comp be less{} and proj be identity{} for the overloads with no parameters by those names.
-9- Preconditions: For the first form, T meets the Cpp17LessThanComparable requirements (Table [tab:cpp17.lessthancomparable]).
-10- Returns: The larger value.
Returns the first argument when the arguments are equivalent.
Effects: Equivalent to:
return invoke(comp, invoke(proj, a), invoke(proj, b)) ? b : a;
-11- Complexity: Exactly one comparison
and two applications of the projection, if any.
-12- Remarks: An invocation may explicitly specify an argument for the template parameter T of the overloads in namespace std.
template<class T> constexpr T max(initializer_list<T> r); template<class T, class Compare> constexpr T max(initializer_list<T> r, Compare comp); template<copyable T, class Proj = identity, indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> constexpr T ranges::max(initializer_list<T> r, Comp comp = {}, Proj proj = {}); template<input_range R, class Proj = identity, indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*> constexpr range_value_t<R> ranges::max(R&& r, Comp comp = {}, Proj proj = {});
-?- Let comp be less{} and proj be identity{} for the overloads with no parameters by those names.
-13- Preconditions: ranges::distance(r) > 0. For the overloads in namespace std, T meets the Cpp17CopyConstructible requirements (Table [tab:cpp17.copyconstructible]). For the first form, T meets the Cpp17LessThanComparable requirements (Table [tab:cpp17.lessthancomparable]).
-14- Returns: The largest value in the input range.
Returns a copy of the leftmost element
when several elements are equivalent to the largest.
Returns a copy of the leftmost element e
in the input range r for which
bool(invoke(comp, invoke(proj, e), invoke(proj, x)))
is false for all elements x in r.
-15- Complexity: Exactly ranges::distance(r) - 1 comparisons
and twice as many applications of the projection, if any.
-16- Remarks: An invocation may explicitly specify an argument for the template parameter T of the overloads in namespace std.
template<class T> constexpr pair<const T&, const T&> minmax(const T& a, const T& b); template<class T, class Compare> constexpr pair<const T&, const T&> minmax(const T& a, const T& b, Compare comp); template<class T, class Proj = identity, indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> constexpr ranges::minmax_result<const T&> ranges::minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {});
-?- Let comp be less{} and proj be identity{} for the overloads with no parameters by those names.
-17- Preconditions: For the first form, T meets the Cpp17LessThanComparable requirements (Table [tab:cpp17.lessthancomparable]).
-18- Returns: {b, a}
if b is smaller than a
bool(invoke(comp, invoke(proj, b), invoke(proj, a))) is true
,
and {a, b} otherwise.
-19- Complexity: Exactly one comparison
and two applications of the projection, if any.
-20- Remarks: An invocation may explicitly specify an argument for the template parameter T of the overloads in namespace std.
template<class T> constexpr pair<T, T> minmax(initializer_list<T> t); template<class T, class Compare> constexpr pair<T, T> minmax(initializer_list<T> t, Compare comp); template<copyable T, class Proj = identity, indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> constexpr ranges::minmax_result<T> ranges::minmax(initializer_list<T> r, Comp comp = {}, Proj proj = {}); template<input_range R, class Proj = identity, indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*> constexpr ranges::minmax_result<range_value_t<R>> ranges::minmax(R&& r, Comp comp = {}, Proj proj = {});
-?- Let comp be less{} and proj be identity{} for the overloads with no parameters by those names.
-21- Preconditions: ranges::distance(r) > 0. For the overloads in namespace std, T meets the Cpp17CopyConstructible requirements (Table [tab:cpp17.copyconstructible]). For the first form, T meets the Cpp17LessThanComparable requirements (Table [tab:cpp17.lessthancomparable]).
-22- Returns: Let X be the return type.
Returns X{x, y},
where x is a copy of the leftmost element
with the smallest value
in the input range r for which
bool(invoke(comp, invoke(proj, e), invoke(proj, x)))
is false for all elements e in r,
and y is a copy of the rightmost element
with the largest value in the input range
in r for which
bool(invoke(comp, invoke(proj, y), invoke(proj, e)))
is false for all elements e in r
.
-23- Complexity: At most (3/2)ranges::distance(r)
applications of the corresponding predicatecomparisons
and twice as many applications of the projection, if any.
-24- Remarks: An invocation may explicitly specify an argument for the template parameter T of the overloads in namespace std.
Editorial issue #6747 finds it inconsistent that the wording for the max, min, and minmax algorithms uses "larger" and "smaller" - terms normally applied to physical quantities - to refer to relationships between values which we term "greater" and "lesser" everywhere else in the Working Paper. Using "greater" and "lesser" would make it no less (pun intended) of a problem that we describe the ordering imposed by an arbitrary binary predicate as if it is a less-than ordering.
For example, [alg.min.max] para 2 says that std::ranges::min(13, 42, std::greater{}) "Returns: The smaller value. Returns the first argument when the arguments are equivalent." The smaller of 13 and 42 is 13, which is not what this call yields. The reader is supposed to somehow know that "The smaller value" actually means "the value we'd call the lesser if the arguments were numbers and comp described a less-then ordering." It would be clearer and more concise to simply say it returns b if invoke(comp, invoke(proj, b), invoke(proj, a)) yields true and a otherwise.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-10-20 04:39:06 | admin | set | messages: + msg14440 |
2024-10-20 00:00:00 | admin | create |