Как работает `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
просто передает свои аргументы этому оператору.