如何格式化或输出std::filesystem::path对象?
如何格式化std::filesystem::path对象
我编写了以下C++函数,但不清楚如何直接格式化std::filesystem::path对象:
const auto load_test_file(std::filesystem::path filename) { std::ifstream ifile(filename, std::ios::in | std::ios::binary); if(!ifile.is_open()) { const auto error_message = std::format("failed to open file {}", filename.string()); throw std::runtime_error(error_message.c_str()); } // do some stuff here }
选择std::filesystem::path作为参数类型的原因:
- std::string_view与std::ifstream、std::ofstream的构造函数不兼容,底层C API要求传入空终止字符串,而std::string_view无法保证这一点
- 不想传递std::string&,因为用char*替代已构造的std::string对象会存在效率问题(虽然在单元测试场景下这点影响不大),因此认为std::filesystem::path是该场景下最合适的类型。
请问有没有方法可以直接格式化std::filesystem::path?
解决方案
1. 直接调用path的字符串转换方法(当前实现方式)
你现在使用的filename.string()是完全可行的方案,它会返回一个std::string类型的路径字符串,可以直接用于std::format。如果需要适配宽字符场景,也可以使用filename.wstring(),不过std::format对std::string的支持更直接。
2. 为std::filesystem::path特化std::formatter(C++20+)
如果想要更优雅地直接在std::format中使用path对象,无需每次手动调用.string(),可以为std::formatter模板做特化:
#include <format> #include <filesystem> namespace std { template <> struct formatter<std::filesystem::path> : formatter<std::string> { template <typename FormatContext> auto format(const std::filesystem::path& p, FormatContext& ctx) { return formatter<std::string>::format(p.string(), ctx); } }; }
完成特化后,就可以直接这样写:
const auto error_message = std::format("failed to open file {}", filename);
这种方式更简洁,符合格式化API的使用习惯。需要注意的是,该特化必须放在std命名空间下,且仅支持C20及更高版本(因为std::format是C20引入的特性)。
3. C++17兼容方案(无std::format)
如果你的项目基于C++17(仅支持std::filesystem但没有std::format),可以使用std::ostringstream来拼接错误信息:
std::ostringstream oss; oss << "failed to open file " << filename; throw std::runtime_error(oss.str());
std::filesystem::path已经重载了<<运算符,因此可以直接输出到流中。
内容的提问来源于stack exchange,提问作者user2138149
相关产品推荐
相关产品推荐

