Почему flat_set и flat_map не являются ContiguousRange? - PullRequest
4 голосов
/ 09 октября 2019

Это сделано специально (отсутствие функции-члена data())? Он предотвращает затухание от flat_set / flat_map до std::span, что может быть полезно, если мы рассмотрим flat_set / flat_map как отсортированные vector.

Безопасно ли делать что-то подобное?

template<typename T>
std::span<const T> make_span(const std::flat_set<T>& fset)
{
    return std::span<const T>{fset.empty() ? nullptr : std::addressof(*fset.begin()),
                              fset.size()};
}

1 Ответ

6 голосов
/ 09 октября 2019

std::flat_set должен быть контейнером адаптером (например, std::queue или std::stack) и должен специально работать с серверными бэкэндами, которые поддерживают итерацию произвольного доступа, например std::vector и * 1007. * делать. Из P1222 (предложение std::flat_set):

Любой контейнер последовательности, поддерживающий итерацию произвольного доступа, может использоваться для создания экземпляра flat_set. В частности, могут использоваться vector и deque.

Никаких требований не предъявляется к любой смежной природе хранилища, а std::deque действительно не имеет data()функция, и при этом он не хранит свои элементы в непрерывном диапазоне. Это означает:

  1. Да, это сделано специально. Поскольку std::flat_set должен быть адаптером, доступ к возможному смежному диапазону может быть делегирован бэкэнду, а требования для std::flat_set могут быть более гибкими.

  2. YouШаблон make_span должен быть безопасным, поскольку он принимает только экземпляры std::flat_set с базовым контейнером по умолчанию, std::vector. Я думаю, что это немного опасно - когда компиляция завершается неудачно для std::flat_set<T, std::deque<T>>, у кого-то может возникнуть желание добавить второй параметр шаблона std::flat_set<T, Container<T>> и работать в UB при доступе к элементам за пределами первого базового std::deque сегмента.

Также обратите внимание, что std::flat_map в его текущей форме использует два отдельных контейнера для хранения ключей и значений, чтобы улучшить локальность кэша при поиске подходящего ключа. Даже если std::flat_map требуется непрерывный бэкэнд, это не может совпасть с полноценной std::flat_map::data() функцией доступа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...