Оператор <=>
От: x-code  
Дата: 27.09.21 19:02
Оценка:
Добрый день
Объясните пожалуйста, в чем разница между equal и equivalent, почему такие порядки сравнения (partial_ordering, weak_ordering, strong_ordering)?
Удачная ли такая система сравнения или нет?
Предусмотрены ли в ней порядки сравнения для объектов, у которых нет понятия "больше" или "меньше", а есть только "равно" или "не равно"?
Как учитывается возможность "несравнимости" объектов (к примеру всякие NaN)?
У меня пока не складывается общая картинка.
Re: Оператор <=>
От: watchmaker  
Дата: 27.09.21 20:44
Оценка:
Здравствуйте, x-code, Вы писали:


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)?

Каждый следующий класс накладывает больше ограничений на результат сравнения. Как в наследовании.
Re[2]: Оператор <=>
От: x-code  
Дата: 28.09.21 06:28
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>То есть текущий подход: для таких объектов нужно определить operator==, но не operator<=>. И если порядок ввести нельзя, то и operator<=> не нужен.


ОК, с этим понятно.

W>Типичный пример: сравнение строк без учёта регистра. Строки "Foo" и "foo" в этом случае эквивалентны (std::weak_ordering::equivalent), но различимы при сравнении с учётом регистра (не std::strong_ordering::equal).


Пример понятен, но не понятно зачем это нужно было вводить в оператор <=>.
А если есть несколько уровней "эквивалентности"?
Например можно сравнивать строки без учета регистра, а можно еще и без учета пробелов в начале и конце строки.
А можно наоборот, ввести еще более строгое равенство — "идентичность", когда сравниваются не только сами строки но и адрес их размещения в памяти. И т.д.

Зачем понадобилось вводить два вида равенства, если оператор == один единственный, и каждый класс все равно может для себя определить понятие равенства в том виде, в каком ему нужно?
Re[3]: Оператор <=>
От: Chorkov Россия  
Дата: 28.09.21 10:41
Оценка:
Здравствуйте, 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>Зачем понадобилось вводить два вида равенства, если оператор == один единственный, и каждый класс все равно может для себя определить понятие равенства в том виде, в каком ему нужно?


Скорее система типов, использована как хранилище метаинформации, о использованном для данного типа способе сравнения.

Что меня смущает — то что на контейнерах и алгоритмах данное нововведение не отразилось...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.