std::flat_set
должен быть контейнером адаптером (например, std::queue
или std::stack
) и должен специально работать с серверными бэкэндами, которые поддерживают итерацию произвольного доступа, например std::vector
и * 1007. * делать. Из P1222 (предложение std::flat_set
):
Любой контейнер последовательности, поддерживающий итерацию произвольного доступа, может использоваться для создания экземпляра flat_set
. В частности, могут использоваться vector
и deque
.
Никаких требований не предъявляется к любой смежной природе хранилища, а std::deque
действительно не имеет data()
функция, и при этом он не хранит свои элементы в непрерывном диапазоне. Это означает:
Да, это сделано специально. Поскольку std::flat_set
должен быть адаптером, доступ к возможному смежному диапазону может быть делегирован бэкэнду, а требования для std::flat_set
могут быть более гибкими.
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()
функцией доступа.