Добрый день
Объясните пожалуйста, в чем разница между equal и equivalent, почему такие порядки сравнения (partial_ordering, weak_ordering, strong_ordering)?
Удачная ли такая система сравнения или нет?
Предусмотрены ли в ней порядки сравнения для объектов, у которых нет понятия "больше" или "меньше", а есть только "равно" или "не равно"?
Как учитывается возможность "несравнимости" объектов (к примеру всякие NaN)?
У меня пока не складывается общая картинка.
XC>Удачная ли такая система сравнения или нет?
ИМХО, Да.
XC>Предусмотрены ли в ней порядки сравнения для объектов, у которых нет понятия "больше" или "меньше", а есть только "равно" или "не равно"?
Вообще — да, но в operator<=> — нет.
Изначально в proposal P0515 были ещё две категории std::weak_equlity и std::strong_equality для описания этого случая.
Но потом их удалили и перенесли их в обычный operator==.
То есть текущий подход: для таких объектов нужно определить operator==, но не operator<=>. И если порядок ввести нельзя, то и operator<=> не нужен.
XC>Как учитывается возможность "несравнимости" объектов (к примеру всякие NaN)? std::partial_ordering::unordered
XC>У меня пока не складывается общая картинка.
См. картинки в proposal
XC>В чем разница между equal и equivalent
Это про strong vs. weak.
Если используется только информация из полей, которые сравнивали, то
* strong — равные объекты неразличимы;
* weak — эквивалентные объекты могут быть различимы.
Типичный пример: сравнение строк без учёта регистра. Строки "Foo" и "foo" в этом случае эквивалентны (std::weak_ordering::equivalent), но различимы при сравнении с учётом регистра (не std::strong_ordering::equal).
XC>почему такие порядки сравнения (partial_ordering, weak_ordering, strong_ordering)?
Каждый следующий класс накладывает больше ограничений на результат сравнения. Как в наследовании.
Здравствуйте, watchmaker, Вы писали:
W>То есть текущий подход: для таких объектов нужно определить operator==, но не operator<=>. И если порядок ввести нельзя, то и operator<=> не нужен.
ОК, с этим понятно.
W>Типичный пример: сравнение строк без учёта регистра. Строки "Foo" и "foo" в этом случае эквивалентны (std::weak_ordering::equivalent), но различимы при сравнении с учётом регистра (не std::strong_ordering::equal).
Пример понятен, но не понятно зачем это нужно было вводить в оператор <=>.
А если есть несколько уровней "эквивалентности"?
Например можно сравнивать строки без учета регистра, а можно еще и без учета пробелов в начале и конце строки.
А можно наоборот, ввести еще более строгое равенство — "идентичность", когда сравниваются не только сами строки но и адрес их размещения в памяти. И т.д.
Зачем понадобилось вводить два вида равенства, если оператор == один единственный, и каждый класс все равно может для себя определить понятие равенства в том виде, в каком ему нужно?
Здравствуйте, x-code, Вы писали:
XC>Здравствуйте, watchmaker, Вы писали:
W>>То есть текущий подход: для таких объектов нужно определить operator==, но не operator<=>. И если порядок ввести нельзя, то и operator<=> не нужен.
XC>ОК, с этим понятно.
W>>Типичный пример: сравнение строк без учёта регистра. Строки "Foo" и "foo" в этом случае эквивалентны (std::weak_ordering::equivalent), но различимы при сравнении с учётом регистра (не std::strong_ordering::equal).
XC>Пример понятен, но не понятно зачем это нужно было вводить в оператор <=>. XC>А если есть несколько уровней "эквивалентности"? XC>Например можно сравнивать строки без учета регистра, а можно еще и без учета пробелов в начале и конце строки. XC>А можно наоборот, ввести еще более строгое равенство — "идентичность", когда сравниваются не только сами строки но и адрес их размещения в памяти. И т.д.
Если смотреть на это не с точки зрения предметной области, а с точки зрения, например, алгоритма сортировки, то не имеет значения, сравниваем мы без учета регистра или без учета пробелов. В обоих случаях сортировку подсчетом применить нельзя.
strong_ordering — это по сути, разрешение алгоритму сортировки присвоить один из равных друг другу объектов другому, (или удалить, а потом воссоздать утраченный копированием).
При этом информация не должна потеряться, поскольку наблюдаемое состояние (которое можно получать через f(A), не должно измениться).
XC>Зачем понадобилось вводить два вида равенства, если оператор == один единственный, и каждый класс все равно может для себя определить понятие равенства в том виде, в каком ему нужно?
Скорее система типов, использована как хранилище метаинформации, о использованном для данного типа способе сравнения.
Что меня смущает — то что на контейнерах и алгоритмах данное нововведение не отразилось...