为什么flat_set和flat_map不是ContiguousRange?

Mam*_*ita 4 c++ templates c++20

是否故意(缺少data()成员函数)完成?它可以防止腐烂从flat_set/ flat_mapstd::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()};
}
Run Code Online (Sandbox Code Playgroud)

lub*_*bgr 6

std::flat_set应该是容器适配器(如std::queuestd::stack),并且应该专门与支持随机访问迭代(如std::vectorand std::dequedo)的容器后端一起使用。从P1222std::flat_set提案):

支持随机访问迭代的任何序列容器都可以用来实例化flat_set。在partic-ular,vector并且deque可以使用。

对于存储的任何连续性质,没有任何要求,并且std::deque实际上没有data()功能,也没有在连续范围内存储其元素。这意味着:

  1. 是的,这是有目的的。由于std::flat_set被认为是一个适配器,获得了底层有可能连续范围可以委托给后端,和用于要求std::flat_set可以更加灵活。

  2. 您的make_span模板应该是安全的,因为它仅接受std::flat_set具有默认基础容器的实例std::vector。但我认为这有点危险-当a的编译失败时std::flat_set<T, std::deque<T>>,可能会有人std::flat_set<T, Container<T>>在访问第一个基础std::deque存储区以外的元素时添加第二个模板参数并运行到UB中。

还要注意,std::flat_map当前形式中,使用两个单独的容器存储键和值,以在搜索匹配的键时提高缓存的位置。即使std::flat_map需要连续的后端,也无法实现有意义的std::flat_map::data()访问功能。