std :: errc,如何在retval中表示成功

时间:2016-04-24 15:37:49

标签: c++ c++14

我想写一个这样的c ++函数:

#include <system_error>
std::errc f() { return std::errc::success; }

但是我无法理解如何使用std :: errc&#39; enum class&#39;来理解如何返回成功的值(在这种情况下为0)。类型。我看到的一种方式是返回int:

template <typename E>
constexpr typename std::underlying_type<E>::type to_underlying(E e) {
    return static_cast<typename std::underlying_type<E>::type>(e);
}

int f() { is_succ() ? 0 : to_underlying(err); }

但对我来说这看起来很难看。是从标准c ++ 0x14中的函数返回面向C的成功/错误代码的标准方法吗?

PS。我正在使用MS VC 2015补丁2。

4 个答案:

答案 0 :(得分:1)

您通常不直接从函数返回git clone值。而是返回std::errc。例如,您的函数将声明如下:

std::error_code

然后将该函数的结果与std :: errc值进行比较。例如:

std::error_code f();

std::error_code error = f(); if (error == std::errc::no_such_file_or_directory) { // deal with the error } 是上下文可转换的bool。测试函数是否成功的方法是使用布尔表达式中的错误代码。例如:

std::error_code

要从此类函数返回成功,您将返回默认的初始化std::error_code error = f(); if (error) { // the function failed... } 。例如:

std::error_code

当您使用 C风格的API时,此方法很有效。您的包装器将使用API​​返回的整数值构建std::error_code f() { // do stuff... return std::error_code{}; // success! } 个对象,并使用自定义std::error_code来定义如何将这些错误转换为std::error_category值。

但是,相反的情况并不奏效。如果您正在为C ++库编写C包装器,那么您必须以C方式执行操作。使用您的错误值定义std::errc并从C入口点返回这些值。

答案 1 :(得分:1)

您可以这样做:

#include <system_error>

std::errc f() { return std::errc(); }

int main()
{
    std::errc x = f();
    if (x == std::errc())
    {
        // success
    }
}

std::errc()(0)是有效的枚举值,即使它没有出现在以1开头的枚举数列表中也是如此。

为进行比较,请看一下std::to_chars,它返回一个

struct to_chars_result {
    char* ptr;
    std::errc ec;
}

答案 2 :(得分:0)

来自the documentation

  

作用域枚举std::errc定义与POSIX错误代码对应的可移植错误条件的值。

std::errc常量用于在您检查是否发生某些特定错误情况时进行比较(如该页面上的示例所示)。

成功不是错误的条件。

返回一个std::error_code,它可以包装其中一个错误条件,或者默认情况下没有错误条件(即成功)。

答案 3 :(得分:0)

您可能会想到一个快速(又肮脏)的问题答案:

// default category is std::system_error
inline std::error_code system_error_code_default{};

您可能会创建系统错误的全局默认实例,该实例的内部值确实为0(零),这是“成功的标志”。然后,您可以使用它来“表示可以恢复”

std::error_code very_complex_operation ()  
{
  return {};
   // same as
  // return error_code_success ;
}

然后您就可以检查返回是否成功

    auto errcde = very_complex_operation();
    auto default_category_name = errcde.category().name();

    if (system_error_code_default == errcde) {
      // the sucess 
    }  else {
      // error condition
    }

这确实可以工作,并且您不必“做任何其他事情”。 但。从逻辑上讲,这都是在“系统”错误类别(也称为域)中发生的。

    // "system"
    auto default_category_name = errcde.category().name();

因此,您在这里属于“系统”错误的领域。如果这是您想要的确定。但我对此表示怀疑。在“玩起”以上内容之后,您将立即想要定义自己的std :: error_code系统,以及自己的枚举,类别,消息和其余内容。信号错误仅与您的API有关。

要了解为什么在存在多个错误类别的情况下只考虑std :: error_code使用模式。了解std名称空间就是这样做的。至少有三个类别。

您的用户/客户端可能正在编写一个C ++应用程序,其中可能有十几个或更多不同的库。如果您使用自己的但标准的std :: error_code系统开发API,使用起来会感觉很“正常”。用户将可能并且愿意将您的API集成到他们的程序中。

我希望这可以更全面地回答这个问题。 如果您希望按照自己的错误代码(甚至更多)的方向进行操作,请proceed here

诚然,基于标准C ++错误代码的处理似乎有点过分设计。我可能认为,理解它的关键是,如果可以的话,要从代码或库的用户的角度出发。