C++17 constexpr容器解析及编译时排序类适配容器问询
嘿,我来帮你把这两个问题的答案理清楚:
在C++17之前,咱们常用的标准容器(比如std::vector、std::array)基本和编译时操作绝缘——你没法在constexpr函数里初始化它们,更别说在编译阶段做插入、修改、排序这些操作了。
C++17的一大改进就是给部分标准容器加上了constexpr支持,简单来说:这些容器可以在编译期间被创建、修改和访问,它们的所有状态都会在编译时就确定下来,到运行时直接用编译好的结果就行,完全不需要运行时的额外计算。
比如std::array在C17里就解锁了一堆constexpr方法:operator[]、front()、back()、fill(),甚至连std::sort都能在constexpr上下文里对它进行排序(只要你的元素类型支持编译时比较)。而std::vector在C17里的constexpr支持就比较有限,只能做固定大小的初始化,没法动态扩容,直到C++20才放开了完整的constexpr能力。
你想要做一个类,有类似std::map的方法,还得在编译时完成排序,而且键K和值V都是模板化的,之前觉得std::vector不太行,后来发现std::array<std::pair<K, V>>能解决问题,我再补充几个适合的选项:
std::array<std::pair<K, V>>:你已经挖到宝了!这确实是C17里最实用的选择。它是固定大小的数组,C17给它的绝大多数方法都加了constexpr支持,包括排序(只要你的键类型K支持编译时的比较运算符)。你完全可以在constexpr函数里对std::array里的pair按键排序,然后封装出类似std::map的查找、遍历方法,所有操作都能在编译时完成,完美适配你的需求。自定义constexpr二叉搜索树:如果你需要动态的元素数量(不像
std::array是固定大小),在C17里可以自己撸一个简化版的constexpr二叉搜索树(比如红黑树或者AVL树的轻量实现)。不过这个工作量不小,而且要注意:C17里不能在constexpr函数里用动态内存分配(new/delete),所以得用静态分配或者依赖模板参数、编译时常量来控制节点的创建和存储。std::vector<std::pair<K, V>>(仅限C++20+):你说std::vector满足不了需求,在C17里确实是这样——它的constexpr支持太受限,没法动态扩容。但如果能升级到C20,std::vector的constexpr能力就完全解锁了:你可以在编译时动态插入元素、排序,用来实现你的类毫无压力。不过要是必须停留在C++17,这个选项就没法用啦。
另外提一句:标准库的std::map在C++17里没有constexpr支持,所以没法直接拿来做编译时的操作,只能自己基于上面这些constexpr容器来封装类似的逻辑。
内容的提问来源于stack exchange,提问作者InFamous X

