man*_*ans 1 c++ boost stl exception
我阅读了一些关于异常和错误代码的使用以及它们何时适合的讨论。
我相信在我的情况下例外更好,但我有一个具体问题:
如果我抛出一个 std::runtime_error("this is an error") 然后我抓住了它,我找不到错误是什么,我只知道有一个错误。
我正在寻找的是一个异常,我可以抛出并为其添加错误代码,以便稍后我可以在捕获它时检查错误代码,例如:
enum errorCodes
{
error_1,
error_2,
error_3
}
try
{
throw std::runtime_error(error_1,"can not do the job!");
}
catch (std::runtime_error & err)
{
switch (err.errorCode)
{
case error_1:
// I can not contunue, so re throw it
rethrow err;
case error_2:
// it is not important for me, so I can continue
break;
case error_3:
//Oh, I need to do something before continue
re_init();
break;
default:
rethrow err;
}
Run Code Online (Sandbox Code Playgroud)
我可以写这样的异常,但在这样做之前,我想知道 STL 或 BOOST 中是否存在这种类型的异常?
有没有更好的方法来做到这一点(我对抛出不同类型的异常不感兴趣,因此从我的角度来看,捕获不同类型的异常不是解决方案。
是的,有std::system_error。它来源于std::runtime_error. 它非常面向 Unix 领域,但它确实支持一般的错误代码,我建议您以这种方式使用它。
以下代码演示了如何为特定于应用程序的错误代码定义自己的错误类别:
#include <string>
#include <system_error>
#include <typeinfo>
namespace my{
struct Error_code
{
enum Enum
{
error_1 = 101,
error_2 = 102,
error_3 = 103
};
};
class App_error_category
: public std::error_category
{
using Base = std::error_category;
public:
auto name() const noexcept
-> char const*
override
{ return "App error"; }
auto default_error_condition( int const code ) const noexcept
-> std::error_condition
override
{ (void) code; return {}; }
auto equivalent( int const code, std::error_condition const& condition ) const noexcept
-> bool
override
{ (void) code; (void) condition; return false; }
// The intended functionality of this func is pretty unclear.
// It apparently can't do its job (properly) in the general case.
auto equivalent( std::error_code const& code, int const condition ) const noexcept
-> bool
override
{ return Base::equivalent( code, condition ); }
auto message( int const condition ) const
-> std::string
override
{ return "An application error occurred, code = " + std::to_string( condition ); }
constexpr
App_error_category(): Base{} {}
};
auto app_error_category()
-> App_error_category const&
{
static App_error_category the_instance;
return the_instance;
}
class App_error
: public std::system_error
{
using Base = std::system_error;
public:
auto app_error_code() const
-> Error_code::Enum
{ return static_cast<Error_code::Enum>( code().value() ); }
App_error( Error_code::Enum const code )
: Base{ code, app_error_category() }
{}
App_error( Error_code::Enum const code, std::string const& description )
: Base{ code, app_error_category(), description }
{}
};
} // namespace my
void foo()
{
try
{
throw my::App_error( my::Error_code::error_1, "can not do the job!" );
}
catch( my::App_error const& x )
{
switch( x.app_error_code() )
{
case my::Error_code::error_1:
// I can not contunue, so re throw it
throw;
case my::Error_code::error_2:
// it is not important for me, so I can continue
break;
case my::Error_code::error_3:
//Oh, I need to do something before continue
//re_init();
break;
}
}
}
#include <iostream>
#include <stdlib.h> // EXIT_SUCCESS, EXIT_FAILURE
using namespace std;
auto main()
-> int
{
try
{
foo();
return EXIT_SUCCESS;
}
catch( exception const& x )
{
cerr << "!" << x.what() << endl;
}
return EXIT_FAILURE;
}
Run Code Online (Sandbox Code Playgroud)
使用 Visual C++ 2015 和 MingW g++ 6.4.0 这会产生输出
!cannot do the job!: 发生应用程序错误,代码 = 101
一般来说,定义特定的异常类比使用错误代码更实用。但是,对于系统错误代码,将这些代码与异常一起传递更为实用。为此,可以避免上面显示的复杂性,因为std::system_category非常适合。
简而言之,这里的复杂性源于您要求不随波逐流,而是要逆流而上。
| 归档时间: |
|
| 查看次数: |
3089 次 |
| 最近记录: |