关于std::filesystem::path组件能否以视图方式访问(无需拷贝)的技术问询
关于std::filesystem::path组件能否以视图方式访问(无需拷贝)的技术问询
我在使用std::filesystem::directory_iterator或std::filesystem::recursive_directory_iterator遍历目录时,经常需要按特定规则过滤结果,通常会写出这样的代码:
template <typename DirectoryIterator, typename T> void for_dirents_in_path(const std::filesystem::path& path, T callback) { std::error_code ec; for (auto& dirent : DirectoryIterator(path, ec)) { if (!dirent.is_regular_file()) { continue; } callback(std::move(dirent)); } } template <typename DirectoryIterator = std::filesystem::directory_iterator, typename T> void for_dirents_with_filename(const std::filesystem::path& path, const std::string& filename, T callback) { for_dirents_in_path<DirectoryIterator>( path, [&](const std::filesystem::directory_entry&& dirent) { // 你也可以根据 dirent.path().extension() 之类的条件过滤 if (dirent.path().filename() != filename) { return; } callback(std::move(dirent)); }); }
但我发现,std::filesystem::path的所有访问器(比如filename()、extension())都会返回内部组件的拷贝——这在扫描大型目录(尤其是递归扫描)时效率极低,debug模式下问题更突出:STL会插入大量运行时检查,导致上面的代码基本没法用在debug环境里。
为了优化性能,我开始手动解析路径组件:通过path().native()获取原生字符串,计算分隔符的偏移位置,再用平台特定的比较函数(比如Windows上的CompareStringOrdinal)。但这种实现很快就变得难以维护,而且特别闹心——因为我能清楚看到STL内部是用零拷贝的视图方式实现这些访问器的,比如这段STL内部代码:
_NODISCARD inline wstring_view _Parse_filename(const wstring_view _Str) { // 尝试将 _Str 解析为路径,返回文件名(如果存在);否则返回空视图 const auto _First = _Str.data(); const auto _Last = _First + _Str.size(); const auto _Filename = _Find_filename(_First, _Last); return wstring_view(_Filename, static_cast<size_t>(_Last - _Filename)); } _NODISCARD path filename() const { // 解析 *this 中的文件名并返回拷贝(如果存在);否则返回空路径 return _Parse_filename(_Text); }
理想情况下,std::filesystem::path应该提供直接获取组件视图的方法,但我没找到官方支持的途径。想问问各位:是我漏看了什么文档或API,还是这确实是C++标准规范里的一个疏漏?
内容来源于stack exchange
相关产品推荐
相关产品推荐

