Title
(greater|less|greater_equal|less_equal)<void> do not yield a total order for pointers
Status
c++17
Section
[comparisons]
Submitter
Joaquín M López Muñoz

Created on 2014-10-30.00:00:00 last changed 90 months ago

Messages

Date: 2015-11-04.16:49:21

Proposed resolution:

This wording is relative to N4296.

  1. Change [comparisons] p14 as indicated:

    -14- For templates greater, less, greater_equal, and less_equal, the specializations for any pointer type yield a total order, even if the built-in operators <, >, <=, >= do not. For template specializations greater<void>, less<void>, greater_equal<void>, and less_equal<void>, if the call operator calls a built-in operator comparing pointers, the call operator yields a total order.

Date: 2015-11-04.16:49:21

[ 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.

Date: 2017-02-02.00:41:18

[ 2015-06, Telecon ]

MC: STL on the hook to update. He's shipping something today so not here.
MC: also add link to N4229

Date: 2015-05-05.21:04:39

[ 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

Date: 2015-03-29.13:43:46

[ 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.

Date: 2015-03-02.20:01:41

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 [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.

  1. Change [comparisons] p14 as indicated:

    -14- For templates greater, less, greater_equal, and less_equal, the specializations for any pointer type yield a total order, even if the built-in operators <, >, <=, >= do not. For template specializations greater<void>, less<void>, greater_equal<void>, and less_equal<void>, the call operator with arguments whose common type CT is a pointer yields the same value as the corresponding comparison function object class specialization for CT.

History
Date User Action Args
2017-07-30 20:15:43adminsetstatus: wp -> c++17
2016-03-07 04:11:48adminsetstatus: ready -> wp
2015-11-04 16:49:21adminsetmessages: + msg7604
2015-11-04 16:49:21adminsetstatus: open -> ready
2015-09-27 20:30:23adminsetmessages: + msg7547
2015-05-05 21:04:39adminsetmessages: + msg7359
2015-05-05 21:04:39adminsetstatus: new -> open
2015-03-02 20:01:41adminsetmessages: + msg7234
2014-10-30 21:36:42adminsetmessages: + msg7160
2014-10-30 00:00:00admincreate