admin管理员组文章数量:1599448
在C语言中处理错误,用枚举,然后调用完后,检测返回值; enum errors { SUCCESS = 0, NOTFOUND, }; int openFile(const char *filename, int *pfd) { int fd = open(filename, , O_RDONLY); if (fd == -1) return NOTFOUND; *pfd = fd; return SUCCESS; }
这样,各个不同错误的枚举可能冲突;
而在C++11中,用异常表示错误:
int openFile(const char *filename) { int fd = open(filename, , O_RDONLY); if (fd == -1) throw std::exception("File not fould"); return fd; }
C++11中,从 boost引入了error_code
int openFile(const char *filename, std::error_code &ec) { int fd = open(filename, , O_RDONLY); if (fd == -1) ec = std::error_code(errno, std::system_category()); return fd; } std::error_code ec; int fd = openFile(filePath, ec); if (ec) { std::cout << "Category: " << ec.category().name() << "Value: " << ec.value() << '\n' << "Message: " << ec.message() << '\n'; }
每个分类,有自己的error_code,这样就避免了枚举冲突;同时也引入了error_condition;
- error_code 基本上是比較底層的錯誤碼,針對有可能會因為作業系統實作的不同
- error_condition 則是和平台差異無關(platform-independent)的錯誤碼,主要是用來做比較用的
而兩者也是可以拿來做比較的,不過 error_code 和 error_code 比較時,是確認是否完全相同;但是拿 error_code 和 error_condition 必較的時候,則是確認兩者是否「等價」,這部分算是比較不一樣的地方。
C++17:
std::error_code ec; std::filesystem::copy_file("aaa", "bbb", ec); if (ec) std::cout << ec << "\n" << ec.message() << std::endl;
在 Windows 平台上,錯誤會是:
system:80 檔案存在。
但是在 Linux 環境的話,他的錯誤會是:
generic:17 File exists
可以看到,雖然這邊是同樣一個錯誤狀況,但是因為平台的不同,所以拿到的 error_code 不管是 error_category 或是錯誤代碼,都是不一樣的。
而和平台差異性無關的 error_condition 就是為了解決這個問題而設計的。
int fd = openFile(filePath, ec); std::error_condition cond1(1, std::system_category()); std::error_condition cond2(2, std::system_category()); if (ec == cond1) { } else if (ec == cond2) { } else { }
定义自己的error_code 需要的函数:
std::is_error_code_enum
std::error_code
定义于头文件 | ||
template< class T > | (C++11 起) | |
若 T
是错误码枚举,则此模板提供等于 true 的成员常量 value 。对于任何其他类型, value
为 false 。
此模板可以为用户定义类型特化,以指示该类型适合于 std::error_code 及 std::error_condition 自动转换。
std::is_error_code_enum 鉴别枚举是否可作为 std::error_condition,若 T 是错误码枚举,则此模板提供等于 true 的成员常量 value 。对于任何其他类型, value 为 false 。
此模板可以为用户定义类型特化,以指示该类型适合于 std::error_code 及 std::error_condition 自动转换。
#include <iostream>
using namespace std;
#include <system_error>
#include <cassert>
namespace mylib
{
namespace errc {
enum my_error
{
failed = 0
};
inline const char* error_message(int c)
{
static const char* err_msg[] =
{
"Failed",
};
assert(c < sizeof(err_msg) / sizeof(err_msg[0]));
return err_msg[c];
}
class my_error_category : public std::error_category
{
public:
my_error_category()
{ }
std::string message(int c) const
{
return error_message(c);
}
const char* name() const noexcept { return "My Error Category"; }
const static error_category& get()
{
const static my_error_category category_const;
return category_const;
}
};
inline std::error_code make_error_code(my_error e)
{
return std::error_code(static_cast<int>(e), my_error_category::get());
}
} // end namespace errc
} // end namespace mylib
namespace std {
template<>
struct is_error_code_enum<mylib::errc::my_error>
: std::true_type
{ };
} // end namespace std
int main()
{
std::error_code ec1 = mylib::errc::make_error_code(mylib::errc::failed); // works
std::error_code ec2 = mylib::errc::failed; // works
bool result = (ec2 == mylib::errc::failed); // works
std::cout << ec1 << std::endl;
}
本文标签: errorcodeerrorconditionamp
版权声明:本文标题:C++11 error_code & error_condition. 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1728322333a1153988.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论