Использование std::less<Bar*>
достаточно (но использование operator<
не достаточно). Специализация указателя std::less
(как принятый ответ на "Использование std :: less with nullptr" указывает на) гарантирует общее упорядочение . Сравнение с nullptr
является неопределенным , что означает, что стандарт не налагает конкретное упорядочение, но std::less
все равно должно производить a общее упорядочение (и для данный указатель p
, p < nullptr
обязательно выдает одно и то же значение каждый раз).
Поскольку общий порядок сильнее слабого, в вашем случае достаточно использовать std::less
.
РЕДАКТИРОВАТЬ: Если нет, то как правильно (например, как объединить std :: less с std :: tie)?
Чистого пути, к сожалению, нет. Поскольку std::tie
возвращает std::tuple
, а сравнение для кортежей определяется в терминах operator<
по их значениям (а не std::less
), вы не можете использовать std::tie
здесь. Чтобы использовать std::less
, вам придется сделать это вручную:
bool operator<(const Foo& rhs) const {
if (std::less<>{}(x, rhs.x))
return true;
if (std::less<>{}(rhs.x, x))
return false;
return std::less<>{}(y, rhs.y);
}
Кроме того, ваша текущая реализация (реинтерпретация указателей как целых чисел) также производит полное упорядочение (очевидно, поскольку вы сравниваете целые числа), но вместо неопределенного поведения у вас будет Поведение, определяемое реализацией (из reinterpret_cast
).