十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

fmt 如何用 as_identifiers 注解把枚举值格式化为枚举名称

fmt 如何用 as_identifiers 注解把枚举值格式化为枚举名称 fmt 如何用 as_identifiers 注解把枚举值格式化为枚举名称【免费下载链接】fmtA modern formatting library项目地址: https://gitcode.com/GitHub_Trending/fm/fmt在 C 日志和调试输出里直接打印一个 scoped enum 经常需要先强转成整型得到的是1、42这样的数字而不是red、green这样的名字。{fmt} 的fmt/enum.h提供了fmt::as_identifiers注解给枚举类型加上这个注解后fmt::format/fmt::print会直接把枚举值格式化为与之匹配的枚举项标识符。本文给出从标注枚举、编译到验证输出结果的完整路径。前提是你的编译器支持 C26 的 reflection 和 annotations 特性——文档明确说明这是该功能的硬性要求例如 GCC 可能需要额外的编译标志-freflection。前提确认编译器是否支持 reflection功能可用性由宏FMT_USE_REFLECTION决定它被设为1当编译器提供 reflection检测__cpp_impl_reflection与__cpp_lib_reflection两个特性宏设为0否则。用户也可以自己定义该宏来关闭reflection 的使用。没有 reflection 支持时仓库自带的测试 test/enum-test.cc 的行为是只打印一行Reflection is not supported.然后跳过所有断言也就是说枚举格式化功能整体不生效而不是编译失败。如果以 C 模块方式使用 {fmt}文档还有一条边界reflection 支持在模块本身被编译时检测因此只有当模块是在启用 reflection 的情况下构建的import 方才能使用这套 API。给枚举添加 as_identifiers 注解fmt/enum.h中定义了注解值本身见 include/fmt/enum.hFMT_EXPORT inline constexpr auto as_identifiers as_identifiers_t();文档给出的用法是把注解直接写在枚举声明上并#include fmt/enum.h#include fmt/enum.h enum class [[fmt::as_identifiers]] color { red, green, blue }; fmt::print({}, color::green); // Output: green文档同时注明clang-format 目前还不支持注解语法仓库测试代码里在用注解的枚举前后加了// clang-format off/// clang-format on来避免被格式化工具打乱如果你的项目跑 clang-format 可以照做。未加注解的枚举行为不变fmt::is_formattablecolor::value对带注解的枚举为true对不带注解的枚举为false见 test/enum-test.cc 中的annotation_is_required测试。未标注的 scoped enum 仍需要走format_as或formatter特化这条路。格式化的具体行为与验证文档doc/api.md 的 Enum Formatting 一节给出的示例输出如下可作为运行后的核对基准匹配到枚举项时输出标识符fmt::print({}, color::green); // Output: green支持字符串格式说明符按 Format Specification 处理fmt::print([{:7}], color::red); // Output: [ red]仓库测试里还有{:*^7}→**red**、{:.2}→gr的用法见 test/enum-test.cc 的format_enum_specs测试。多个枚举项取相同值时使用声明顺序中第一个enum class [[fmt::as_identifiers]] alias { one 1, uno 1 }; fmt::format({}, alias::uno); // 结果为 one没有匹配枚举项的值按底层值以十进制表示再套用字符串格式fmt::print({}, static_castcolor(42)); // Output: 42测试中还覆盖了几个容易踩坑的底层类型char底层类型不匹配时按十进制数字输出static_castbyte_enum(65)输出65而不是字符Abool底层类型输出1/0而不是true/false带负值的枚举如minus_two -2可以正常解析出标识符。这些都可以直接在你的验证程序里复现。编译与运行验证接入方式按你项目的现有构建体系选一种即可文档doc/get-started.md列出的 CMake 路径有三种FetchContentCMake 3.11FetchContent_Declare(fmt ...)后FetchContent_MakeAvailable(fmt)再target_link_libraries(your-target fmt::fmt)Installedfind_package(fmt)后链接fmt::fmtEmbedded把 {fmt} 源码树放进工程add_subdirectory(fmt)后链接fmt::fmt。要启用注解功能编译时开启编译器对 reflection 的支持GCC 示例标志为-freflection。验证是否生效的最小程序就是上面的color例子编译运行后看到green输出即代表注解生效如果FMT_USE_REFLECTION为 0功能不可用行为等同未引入该头文件。在仓库内做完整验证按文档的源码构建流程走mkdir build cd build cmake .. make make test其中enum-test是注册在 test/CMakeLists.txt 中的正式测试项覆盖了基础格式化、未作用域枚举、各种底层类型、未匹配值回退、格式说明符以及is_formattable判定全部通过即说明当前工具链下该功能工作正常。限制文档明确给出的边界有两条编写代码时需要注意标识符只能是char字符串带注解的枚举不能用其他字符类型如wchar_t格式化只对加了注解的枚举生效同一工程里未标注的枚举行为保持原样不会意外改变输出。另外测试中展示了内部实现按枚举值密度选择查表或哈希表两种查找方式如dense/holey/sparse几个测试枚举但这属于实现细节对使用方来说无论哪种路径上面的格式化和回退行为是一致的。【免费下载链接】fmtA modern formatting library项目地址: https://gitcode.com/GitHub_Trending/fm/fmt创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表