如何在 C++ 中无异常地使用 recursive_directory_iterator(..)

问题描述 投票:0回答:2

我使用 recursive_directory_iterator 来迭代目录。当传递的路径不存在时,迭代器似乎会抛出异常。有没有一种方法可以在不启用异常的情况下使用迭代器?

// try / catch can't be used here
for (auto const& dir_entry : fs::recursive_directory_iterator("I-dont-exist"))
{
    std::cout << dir_entry << '\n';
}
c++ exception c++17
2个回答
1
投票

来自 cppreference.com 的文章

采用 std::error_code& 参数的重载设置它 如果操作系统 API 调用失败,则返回操作系统 API 错误代码,并执行 ec.clear() 如果没有出现错误。

这个构造函数没有被标记为

noexcept
的原因很可能是因为,迂腐地,它可能会因为与不存在的目录或路径无关的原因而抛出异常。这只保证在文件系统问题(例如不存在的目录)的情况下不会出现异常。由于您希望防止因此原因引发异常,因此这应该可行。

您的下一个任务是构造

std::filesystem::path
而不抛出异常。

std::filesystem::path
构造函数定义如下:“可能抛出实现定义的异常”,如果他们愿意,出于任何原因,全权委托抛出异常。

但是,实际上,这是指有效路径的文件系统路径。尝试在 MS-Windows 上构建“/:\WINDOWS\SYSTEM”的路径可能会为您带来这些“实现定义”的异常之一。

如果您提供的路径字符串是操作系统上有效的路径字符串,则不会抛出异常。

最后,

std::filesystem::path
的构造函数是隐式的。对于您的用例,避免异常可以归结为:

  1. 构造递归目录迭代器时传递有效路径。您可以根据操作系统文件名的规则来验证它。

  2. 使用引用错误代码对象的重载作为附加参数。


0
投票

我认为之前的任何一个答案都不能解决问题。

问题在于基于范围的 for 循环隐式使用operator++() 来递增迭代器。请参阅https://en.cppreference.com/w/cpp/language/range-for

但是,如果你想要非抛出迭代器,签名是

recursive_directory_iterator& increment( std::error_code& ec );

(参见 https://en.cppreference.com/w/cpp/filesystem/recursive_directory_iterator/increment)。

这意味着您需要编写一个老式的 for 循环。

类似这样的事情

  std::error_code ec;
  using recursive_directory_iter =
      std::filesystem::recursive_directory_iterator;
  auto dirEntry = std::filesystem::begin(recursive_directory_iter(dir, ec));
  for ( ; dirEntry != std::filesystem::end(recursive_directory_iter(dir, ec)); dirEntry.increment(ec)) {
© www.soinside.com 2019 - 2024. All rights reserved.