Сортировка по адресу элемента ⇐ C++
-
Anonymous
Сортировка по адресу элемента
Я столкнулся с ситуацией, когда библиотека сортирует контейнер (например, std::vector) с помощью предоставленного пользователем объекта сравнения. В одном конкретном случае пользователь на самом деле не хочет сортировать контейнер, но сортировка происходит безоговорочно.
Итак, чтобы избежать этой ситуации, я подумал попробовать использовать объект сравнения, который сортируется по адресу элемента. Аналогично, мы имеем:
std::vector nums{1, 5, 4}; auto cmp = [](auto& a, auto& b) { return &a < &b; }; std::sort(nums.begin(), nums.end(), cmp); Это «работает», потому что элементы std::vector хранятся в (непрерывных) ячейках памяти в том же порядке, что и элементы в векторе. Конечным результатом является то, что вектор nums, похоже, остался нетронутым даже после сортировки.
Однако, как только я заменю std::vector на std::array, я получу нарушение сегментации (см. https:/ /gcc.godbolt.org/z/9srehdbhG).
Моя первая мысль: я нарушаю требования к типам, перечисленные на https://en.cppreference.com/w/cpp/algorithm/sort:
[*]RandomIt должен соответствовать требованиям ValueSwappable и LegacyRandomAccessIterator. [*]Тип разыменованного RandomIt должен соответствовать требованиям MoveAssignable и MoveConstructible. [*]Сравнить должен соответствовать требованиям Сравнить.
Я предполагал, что адреса элементов будут оставаться стабильными на протяжении всей сортировки — это почти наверняка неверно.
Итак, какие требования/предварительные условия std::sort() я нарушаю?
Я столкнулся с ситуацией, когда библиотека сортирует контейнер (например, std::vector) с помощью предоставленного пользователем объекта сравнения. В одном конкретном случае пользователь на самом деле не хочет сортировать контейнер, но сортировка происходит безоговорочно.
Итак, чтобы избежать этой ситуации, я подумал попробовать использовать объект сравнения, который сортируется по адресу элемента. Аналогично, мы имеем:
std::vector nums{1, 5, 4}; auto cmp = [](auto& a, auto& b) { return &a < &b; }; std::sort(nums.begin(), nums.end(), cmp); Это «работает», потому что элементы std::vector хранятся в (непрерывных) ячейках памяти в том же порядке, что и элементы в векторе. Конечным результатом является то, что вектор nums, похоже, остался нетронутым даже после сортировки.
Однако, как только я заменю std::vector на std::array, я получу нарушение сегментации (см. https:/ /gcc.godbolt.org/z/9srehdbhG).
Моя первая мысль: я нарушаю требования к типам, перечисленные на https://en.cppreference.com/w/cpp/algorithm/sort:
[*]RandomIt должен соответствовать требованиям ValueSwappable и LegacyRandomAccessIterator. [*]Тип разыменованного RandomIt должен соответствовать требованиям MoveAssignable и MoveConstructible. [*]Сравнить должен соответствовать требованиям Сравнить.
Я предполагал, что адреса элементов будут оставаться стабильными на протяжении всей сортировки — это почти наверняка неверно.
Итак, какие требования/предварительные условия std::sort() я нарушаю?
Мобильная версия