Ответ 1
Введение
Этот вопрос действительно сводится к тому, что использование менее реляционного оператора по типам указателей, где один операнд является nullptr
, даст ожидаемый результат; что, к сожалению, не так.
Результат не указан.
Примечание: Имейте в виду, что
std::less
гарантирует общий порядок; что даже если результат при использовании объекта функции не задан, он должен давать то же самое неуказанное значение для каждого вызова.
Что означает Международный стандарт (N3337)?
5.9p2 Реляционные операторы
[expr.rel]
Указатели на объекты или функции одного и того же типа (после конверсий указателей) можно сравнить с результатом, определяемым следующим образом:
Если два указателя
p
иq
того же типа указывают на один и тот же объект или функцию, либо оба указывают один за концом одного и того же массива, либо оба являются нулевыми, тоp<=q
иp>=q
оба выходаtrue
иp<q
иp>q
даютfalse
.Если два указателя
p
иq
того же типа указывают на разные объекты, которые не являются членами одного и того же объекта или элементов одного и того же массива или с разными функциями, или если только один из них null, результатыp<q
,p>q
,p<=q
иp>=q
не определены.Если два указателя указывают на нестатические элементы данных одного и того же объекта или на подобъекты или элементы массива таких элементов, рекурсивно, указатель на более поздний объявленный элемент сравнивается больше, если два члена имеют одинаковый доступ (раздел 11) и при условии, что их класс не является объединением.
Если два указателя указывают на нестатические элементы данных одного и того же объекта с различным контролем доступа (раздел 11), результат не указан.
Если два указателя указывают на нестатические элементы данных одного и того же объекта объединения, они сравнивают одинаковые значения (после преобразования в
void*
, если необходимо). Если два указателя указывают на элементы одного массива или один за концом массива, указатель на объект с более высоким индексом сравнивается выше.Другие сравнения указателей не указаны.
20.8.5p8
Сравнение[comparision]
Для шаблонов
greater
,less
,greater_equal
иless_equal
специализации для любого типа указателя дают полный порядок, даже если встроенные операторы<
,>
,<=
,>=
не.
Итак, что такое стандарт, который действительно говорит?
T * p = new T;
T * q = nullptr;
Каков вердикт для p < q
?
Поскольку p
и q
не указывают на разные элементы одного и того же массива (включая элемент один за последним элементом массива), и оба не указывают на нестатические элементы данных одного и того же объекта; результат при выполнении p < q
(и p > q
) не указан.
bool a = p < q; // unspecified
bool b = p < q; // unspecified
assert (a == b); // can fire
Как насчет std::less
?
Однако при использовании std::less
нам гарантируется полный порядок, что фактически означает, что нижеприведенное утверждение не может fire (standard-20.8.5p8).
std::less<T*> comp;
bool a = comp (p, q); // unspecified
bool b = comp (p, q); // unspecified
assert (a == b); // can not fire