Практическое значение сильного порядка и слабого порядка

Я читал немного о последовательном сравнении C++20 (т.е. operator<=>) но не мог понять, в чем практическая разница между strong_ordering а также weak_ordering (то же самое касается _equality версия для этой манеры).
Кроме того, что он очень наглядно описывает заменяемость типа, действительно ли он влияет на сгенерированный код? Добавляет ли это какие-либо ограничения на то, как можно использовать тип?
Хотелось бы увидеть пример из жизни, который демонстрирует это.

2 ответа

Решение

Добавляет ли это какие-либо ограничения на то, как можно использовать тип?

Одним очень существенным ограничением (которое не было задумано в первоначальном документе) было принятие значения strong_ordering P0732 как индикатор того, что тип класса можно использовать как параметр шаблона нетипичного типа. weak_ordering недостаточно для этого случая из-за того, как должна работать эквивалентность шаблона.

Как правило, возможно, что некоторые алгоритмы просто требуют weak_ordering но другие алгоритмы требуют strong_ordering таким образом, возможность комментировать, что для типа может означать ошибку компиляции (обеспечивается недостаточно строгий порядок) вместо простого несоблюдения требований алгоритма во время выполнения и, следовательно, просто неопределенного поведения. Но все алгоритмы в стандартной библиотеке и диапазонах TS, о которых я знаю, просто требуют weak_ordering, Я не знаю ни одного, который требует strong_ordering с верхней части моей головы.

Это на самом деле влияет на сгенерированный код?

За пределами случаев, когда strong_ordering требуется, или алгоритм явно выбирает другое поведение на основе категории сравнения, нет.

На самом деле нет никаких причин для этого. Верно, что стандарт описывает такие операции, как сортировка, в терминах «строгого» слабого порядка , но существует изоморфизм между строгим слабым порядком и полностью упорядоченным разделением исходного набора на классы эквивалентности несравнимости. Редко можно встретить общий код, который интересуется как структурой порядка (которая рассматривает каждый класс эквивалентности как одно «значение»), так и некоторым, возможно, более тонким понятием эквивалентности : обратите внимание, что когда стандартная библиотека использует < (или <=>) он не использует (что могло бы быть лучше).

Обычный пример для std::weak_orderingявляется строкой без учета регистра, поскольку, например, печать двух строк, которые отличаются только регистром, безусловно, приводит к разному поведению, несмотря на их эквивалентность (под любым оператором). Однако многие типы могут вести себя по-разному, несмотря на то, что ==: два std::vector<int> объекты, например, могут иметь одинаковое содержимое и разную емкость, поэтому добавление к ним может по-разному аннулировать итераторы.

Простой факт состоит в том, что "равенство", подразумеваемое std::strong_ordering::equivalent но не std::weak_ordering::equivalentне имеет отношения к самому коду, который получит от него выгоду, потому что общий код не зависит от подразумеваемых поведенческих изменений, а неуниверсальный код не должен различать типы упорядочивания, потому что он знает правила для типа на которым он управляет.

Стандарт пытается придать этому различию значение, говоря о «заменяемости», но это неизбежно повторяется, потому что оно может разумно относиться только к самому состоянию, исследуемому сравнениями. Это обсуждалось до публикации C++20, но (возможно, по очевидным причинам) не так много запланированного дальнейшего обсуждения.

Другие вопросы по тегам