如何实现constexpr版index_of函数?适配const char*数组与编译期校验
实现兼容ImGui的编译期
index_of函数 核心思路
要满足编译期检查字符串是否存在,同时保持数组类型与ImGui的const char**要求兼容,我们可以利用C++模板推导数组大小,结合编译期字符串比较和递归查找来实现,完全不需要修改原有数组的定义方式。
完整代码实现
#include <cstddef> #include <cstdio> #include <type_traits> // 编译期C字符串比较函数 constexpr bool str_equal(const char* a, const char* b) { while (*a && *b) { if (*a != *b) return false; ++a; ++b; } return *a == *b; } // 递归查找索引的辅助模板 template <std::size_t I, std::size_t N> constexpr std::size_t index_of_impl(const char* const (&arr)[N], const char* target) { if constexpr (I >= N) { // 编译期断言,目标字符串不存在时触发错误 static_assert(I < N, "目标字符串不存在于数组中"); return N; // 永远不会执行到此处 } else if (str_equal(arr[I], target)) { return I; } else { return index_of_impl<I + 1>(arr, target); } } // 对外暴露的接口,从索引0开始查找 template <std::size_t N> constexpr std::size_t index_of(const char* const (&arr)[N], const char* target) { return index_of_impl<0>(arr, target); } // 你的原始数组,保持原有定义不变(元素再多也不影响) static const char* ITEMS[] = { "a", "b" }; void my_func() { printf("a: %zu\n", index_of(ITEMS, "a")); // 编译期计算,输出0 // printf("d: %zu\n", index_of(ITEMS, "d")); // 取消注释会触发编译期断言错误 }
关键细节说明
- 编译期字符串比较:
str_equal是纯constexpr函数,不依赖std::string,完全适配C风格字符串的编译期检查需求。 - 数组大小推导:模板自动推导数组的大小
N,不需要手动指定——即使数组元素数量极多,编译器也能正常处理(这和std::array需要显式指定大小的场景不同,不会触发编译错误)。 - 兼容性保证:原有数组
static const char* ITEMS[]的类型完全不变,传递给ImGui的Combo时,数组名会自动退化为const char**,完美满足接口要求。 - 编译期报错:当目标字符串不存在时,
static_assert会直接在编译阶段抛出错误,不会等到运行时才暴露问题。
内容的提问来源于stack exchange,提问作者Martmists
相关产品推荐
相关产品推荐

