【问题标题】:std::filesystem::exists -- Do I need to check the std::error_code value if the function returns true?std::filesystem::exists -- 如果函数返回 true,我是否需要检查 std::error_code 值?
【发布时间】:2021-07-18 02:40:10
【问题描述】:

std::filesystem::exists 用于检查“给定的文件状态或路径是否对应于现有文件或目录”。在我的代码中,我使用具有以下签名的定义:

bool exists( const std::filesystem::path& p, std::error_code& ec ) noexcept;

我的问题是:如果函数返回布尔值true,我还需要检查错误代码ec的值吗?或者我可以假设,如果std::filesystem::exists 返回true,那么没有错误并且(bool)ecfalse

例如,假设我有以下内容:

std::error_code ec;
std::filesystem::path fpath = "fname";
bool does_exist = std::filesystem::exists(fpath, ec);
if (does_exist) {
    ...
}

是否有必要检查(bool)ec == false 是否在if (does_exist) { ... } 块内?

【问题讨论】:

    标签: c++ c++17 error-code


    【解决方案1】:

    std::filesystem 库直接从对应的Boost library 演变而来。作为 Boost 库中的几个函数(例如 Boost ASIO),它提供了two interfaces 使用不同类型的错误处理

    bool exists(std::filesystem::path const& p);
    bool exists(std::filesystem::path const& p, std::error_code& ec) noexcept;
    

    第一个版本使用异常(必须用try... catch 构造捕获),而第二个版本没有,而是必须评估错误代码。此错误代码可能包含有关失败确切原因的其他信息,如果函数返回false,则有助于调试。

    不带 std::error_code& 参数的重载抛出 底层 OS API 错误上的 filesystem_error,用 p 构造 第一个路径参数和操作系统错误代码作为错误代码 争论。采用 std::error_code& 参数的重载将其设置为 如果 OS API 调用失败,则 OS API 错误代码,并执行 ec.clear() 如果没有错误发生。任何未标记 noexcept 的重载都可能抛出 std::bad_alloc 如果内存分配失败。

    另一方面,如果函数返回 true,则假设路径存在是安全的。

    错误代码更轻量级,尤其适用于实时性能代码、数值模拟和高性能应用程序。在这些情况下,为了获得更好的性能,可能会完全关闭编译过程的异常处理。另一方面,对于嵌套代码,错误代码通常更难维护 - 如果例程在某些子功能中失败 - 您将不得不将错误代码通过多个层传递到应该处理错误的地方。这方面的异常更容易维护。

    【讨论】:

      【解决方案2】:

      来自 cppreference:

      如果 OS API 调用失败,采用 std::error_code& 参数的重载将其设置为 OS API 错误代码,如果没有错误发生,则执行 ec.clear()

      不,你不需要。最好只在调用失败时使用它。任何其他时间ec 都不会包含任何有用的信息。

      您可以使用if-initializer 语句强制执行此操作,因此错误代码仅在可能的最小范围内声明:

      std::filesystem::path fpath{"fname"};
      if(std::error_code ec{}; !std::filesystem::exists(fpath, ec)) {
          std::cerr << "File system returned the following for \"" << fpath.string() << "\":\nError: " << ec.value() << "\nMessage: " << ec.message();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-27
        • 1970-01-01
        • 2021-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-16
        相关资源
        最近更新 更多