在C++23/26中从std::set获取constexpr size生成指定大小容器
解决C++23/26中constexpr环境下从std::set生成frozen::set的问题
核心问题是std::set的迭代器在当前G++版本中不属于字面类型(literal type),无法用于初始化constexpr std::vector——这直接触发了你第14行的错误。以下是针对性的修正方案:
修正后的代码
#include <algorithm> #include <array> #include <set> #include <string_view> #include <vector> #include <frozen/set.h> #include <frozen/bits/basic_types.h> using namespace std::string_view_literals; constexpr auto test(const std::string_view input) { // 1. 在constexpr函数内使用普通std::set收集元素(C++23支持constexpr操作std::set) std::set<std::string_view> my_set; my_set.emplace(input); // 实际场景可灵活添加任意数量元素 // 2. 用普通std::vector中转元素(去掉constexpr修饰,规避迭代器字面类型限制) std::vector<std::string_view> my_vec(my_set.begin(), my_set.end()); // 3. 提取编译期可确定的集合大小(constexpr调用时,size会被推导为编译期常量) constexpr auto set_size = my_vec.size(); // 4. 构造对应大小的std::array并填充元素 std::array<std::string_view, set_size> my_arr{}; std::copy(my_vec.begin(), my_vec.end(), my_arr.begin()); // 5. 转换为frozen::set所需的carray并返回 frozen::bits::carray<std::string_view, set_size> my_carr(my_arr); return frozen::set<std::string_view, set_size>(my_carr); } int main() { constexpr auto frozen_set = test("test"sv); return 0; }
关键修正说明
- 移除constexpr修饰的vector:将
constexpr std::vector改为普通自动存储期的vector——constexpr函数内部允许使用非constexpr变量,只要整个函数的求值过程符合constexpr规则即可,这样就避开了迭代器字面类型的限制。 - 提取编译期大小:通过
constexpr auto set_size = my_vec.size()获取集合大小——当函数以constexpr方式调用时(比如main中传入的是constexpr字符串视图),这个值会被编译器推导为编译期常量,可直接作为std::array和frozen::set的模板参数。 - 兼容C++23 constexpr容器:C23已支持std::set的constexpr修改操作(如emplace),G14开发版的支持完全覆盖该场景。
后续处理复杂元素插入逻辑时,只要保持在constexpr函数内操作普通容器,最后提取编译期可确定的大小即可,无需再担心迭代器的字面类型问题。
内容的提问来源于stack exchange,提问作者Torsten Knodt
相关产品推荐
相关产品推荐

