(greater|less|greater_equal|less_equal)<void>
do not yield a total order for pointersSection: 22.10.8 [comparisons] Status: C++17 Submitter: Joaquín M López Muñoz Opened: 2014-10-30 Last modified: 2017-07-30
Priority: 2
View other active issues in [comparisons].
View all other issues in [comparisons].
View all issues with C++17 status.
Discussion:
less<void>::operator(t, u)
(and the same applies to the rest of void
specializations for standard
comparison function objects) returns t < u
even if t
and u
are pointers, which by
7.6.9 [expr.rel]/3 is undefined except if both pointers point to the same array or object. This might be
regarded as a specification defect since the intention of N3421 is that less<>
can substitute for
less<T>
in any case where the latter is applicable. less<void>
can be rewritten in
the following manner to cope with pointers:
template<> struct less<void> { typedef unspecified is_transparent; template <class T, class U> struct pointer_overload : std::is_pointer<std::common_type_t<T, U>> {}; template < class T, class U, typename std::enable_if<!pointer_overload<T, U>::value>::type* = nullptr > auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) < std::forward<U>(u)) { return std::forward<T>(t) < std::forward<U>(u); } template < class T, class U, typename std::enable_if<pointer_overload<T, U>::value>::type* = nullptr > auto operator()(T&& t, U&& u) const -> decltype(std::declval<std::less<std::common_type_t<T, U>>>()(std::forward<T>(t), std::forward<U>(u))) { std::less<std::common_type_t<T, U>> l; return l(std::forward<T>(t), std::forward<U>(u)); } };
This wording is relative to N4140.
Change 22.10.8 [comparisons] p14 as indicated:
-14- For templates
greater
,less
,greater_equal
, andless_equal
, the specializations for any pointer type yield a total order, even if the built-in operators<
,>
,<=
,>=
do not. For template specializationsgreater<void>
,less<void>
,greater_equal<void>
, andless_equal<void>
, the call operator with arguments whose common typeCT
is a pointer yields the same value as the corresponding comparison function object class specialization forCT
.
[2015-02, Cologne]
AM: Is there any way this will be resolved elsewhere? VV: No. AM: Then we should bite the bullet and deal with it here.
MC: These diamond operators are already ugly. Making them more ugly isn't a big problem. JY found some issue with types that are convertible, and will reword. Jeffrey suggests improved wording.[2015-05, Lenexa]
STL: when diamond functions designed, this was on purpose
STL: this does go against the original design
STL: library is smarter and can give a total order
MC: given that the original design rejected this, give back to LEWG
STL: original proposal did not talk about total order
STL: don't feel strongly about changing the design
STL: no objections to taking this issue with some wording changes if people want it
MC: not happy with wording, comparing pointers — what does that mean?
STL: needs careful attention to wording
STL: want to guarantee that nullptr
participates in total ordering
STL: all hooks into composite pointer type
MC: move from new to open with better wording
STL: to check updates to issue after Lenexa
[2015-06, Telecon]
MC: STL on the hook to update. He's shipping something today so not here.
MC: also add link to N4229
[2015-10, Kona Saturday afternoon]
STL was on the hook for wording, but STL: I don't care. The architecture on which this is an issue does not exist.
STL: We will also need to incorporate nullptr. TK: I think that's implied, since the wording is in terms of the resulting operation, not the deduced types.
STL: Seems legit. MC: I guess I'm OK with this. TK: I'm weakly in favour, so that we can get people to use transparent comparators without worrying.
STL: There's no change to implementations.
Move to Tentatively ready.
Proposed resolution:
This wording is relative to N4296.
Change 22.10.8 [comparisons] p14 as indicated:
-14- For templates
greater
,less
,greater_equal
, andless_equal
, the specializations for any pointer type yield a total order, even if the built-in operators<
,>
,<=
,>=
do not. For template specializationsgreater<void>
,less<void>
,greater_equal<void>
, andless_equal<void>
, if the call operator calls a built-in operator comparing pointers, the call operator yields a total order.