我想写一个这样的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。
答案 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
值。
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)
作用域枚举
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 ++错误代码的处理似乎有点过分设计。我可能认为,理解它的关键是,如果可以的话,要从代码或库的用户的角度出发。