问题描述
我目前正在结束用于基于网格的量子计算的仅 C++ 标头模板库的开发,我正在考虑替换我几乎在开始时编写的旧日志记录模块。
我知道让仅标头库将内容打印到标准输出(和文件)听起来有点奇怪,但我大量使用模板来提高运行时二进制文件的灵活性和效率,因此做出了这个选择。
当前日志模块使用 printf(因为我不喜欢 std::cout
语法)、宏、可变参数宏(##__VA_ARGS__
),支持控制台颜色并使用 {{1} 打印出源中的位置},__FILE__
宏,即既不是现代的也不是类型安全的,但它可以工作。
用 __LINE__
(或类似的东西)替换它是否有意义,或者我应该尝试对现有的进行现代化改造(即用模板替换可变参数宏,自定义构建编译时 fmt
的等)?
我希望图书馆“立即”工作,也就是说,我愿意:
a) 消除尽可能多的依赖
b) 在 CMake 中静默地尝试 string_view
或 FetchContent -(顺便说一句。是否有针对此行为的通用 CMake“模板”?类似于“find_or_fetch”?)
c) 将 find_package(fmt)
的基本部分作为 git 子模块放入我的项目中,并包含一个小头文件。
除此之外,我还计划使用 HDF5 库(有或没有 C++ 包装器)。 再次,我不确定如何最好地处理它以使集成尽可能无缝,我也没有决定应该使用哪个包装器。 “find_or_fetch”范式是否适用于仅标头库?
解决方法
如果我是你,我不会。
- 只有头文件的库意味着简约。
fmt
与此相反。 - 只有头文件的库意味着用户友好。强行依赖用户并不是很友好。
- 如果您在不需要更好的日志记录工具的情况下已经走了那么远,那么您使用的工具很可能已经足够好了。
- 必须匹配格式字符串和参数是不使用
fmt
的最大缺点之一。但是你已经完成了匹配。只要格式字符串是文字,现代编译器就会对任何不匹配发出警告。
如果您进行大量格式化并且{fmt} 旨在支持轻松嵌入,这是有道理的。特别是,它具有零依赖性并且相对较小,最小配置仅由三个中等大小的文件组成。有几个项目嵌入了 {fmt},例如 spdlog。与推出您自己的格式化解决方案相比,其优势在于将来可以轻松移植到 std::format
。