Как работает `std::less`?

Реляционные операторы указателя не определяют полный порядок ( п. 5.9 стандарта C++11):

Если два указателя p а также q одного и того же типа указывают на разные объекты, которые не являются членами одного и того же объекта или элементов одного и того же массива или на разные функции, или, если только один из них равен нулю, результаты p<q, p>q, p<=q, а также p>=q не определены.

Документация std::less гласит:

Частичная специализация std::less для любого типа указателя выдает общий порядок, даже если встроенный operator< не.

Как это дает этот общий заказ из частичного заказа?


Я не могу ответить на этот вопрос, посмотрев на /usr/include/c++/4.9/bits/stl_function.h за struct less определения:

  template<typename _Tp = void>
    struct less;

  template<typename _Tp>
    struct less : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x < __y; }
    };

  template<>
    struct less<void>
    {
      template <typename _Tp, typename _Up>
        auto
        operator()(_Tp&& __t, _Up&& __u) const
        noexcept(noexcept(std::forward<_Tp>(__t) < std::forward<_Up>(__u)))
        -> decltype(std::forward<_Tp>(__t) < std::forward<_Up>(__u))
        { return std::forward<_Tp>(__t) < std::forward<_Up>(__u); }

      typedef __is_transparent is_transparent;
    };

1 ответ

Решение

Как это дает этот общий заказ из частичного заказа?

Стандарт редко говорит о том, как что-то сделать. Вместо этого он говорит, что требуется. И это именно так. Стандарт требует std::less обеспечить общий порядок, в §20.9.6/14:

Для шаблонов "больше", "меньше", "больше_эквивалента" и "меньше_эквивалента" специализации для любого типа указателя дают общий порядок, даже если встроенные операторы <,>, <=, >= этого не делают.

в то время как operator<поведение в этом отношении не определено в соответствии с §5.9/4 (цитата, которую вы имеете в своем вопросе).

Неопределенное поведение определено в §1.3.25 для обозначения:

поведение, для правильно сформированной программной конструкции и правильных данных, которое зависит от реализации [...]

В вашей конкретной реализации, operator< уже обеспечивает полный порядок (вероятно, потому что ваш тип указателя реализован как 32-битный или 64-битный адрес, который можно легко интерпретировать как нечто похожее на целое число без знака, что дает общий порядок), поэтому std::less просто передает свои аргументы этому оператору.

Другие вопросы по тегам