是的,有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;
}
使用 Visual C++ 2015 和 MingW g++ 6.4.0 这会产生输出
!can't do the job!: 发生应用程序错误,代码 = 101
一般来说,定义特定的异常类比使用错误代码更实用。但是,对于系统错误代码,将这些代码与异常一起传递更为实际。而对于,可以避免上面显示的复杂性,因为std::system_category 非常适合。
简而言之,这里的复杂性源于您不随波逐流的要求,而是在某种程度上逆流而上的方向。