C++11 error

C++11 error,第1张

C++11 error
在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 >
struct is_error_code_enum;

(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 
using namespace std;
#include 
#include 

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(e), my_error_category::get());
        }

    } // end namespace errc
} // end namespace mylib

namespace std {

    template<>
    struct is_error_code_enum
        : 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;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5692272.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存