What is a good way to return success or one or more error codes from a C++ function?
从C ++函数返回成功或一个或多个错误代码的好方法是什么?
I have this member function called save(), which saves to each of the member variables, there are at least ten of these member variables that are saved-to, for the call to save(), I want to find out if the call failed, and if so, on which member variable (some are hard failures, some are soft).
我有这个名为save()的成员函数,它保存到每个成员变量中,至少有十个这些成员变量被保存到,对于调用save(),我想找出是否调用失败,如果是这样,关于哪个成员变量(一些是硬故障,一些是软的)。
9 个解决方案
#1
You can either return an object that has multiple error fields or you can use 'out'parameters.
您可以返回具有多个错误字段的对象,也可以使用“out”参数。
How you do this depends on your design and what exactly you are trying to return back. A common scenario is when you need to report back a status code along with a message of sorts. This is sometimes done where the function returns the status code as the return value and then returns the message status via an 'out' parameter.
你如何做到这一点取决于你的设计以及你想要返回的确切内容。常见的情况是,您需要报告状态代码以及各种消息。有时会在函数返回状态代码作为返回值的情况下执行此操作,然后通过“out”参数返回消息状态。
If you are simply returning a set of 'codes', it might make more sense to construct a struct type and return that. In that case, I would be prone to pass it in as an out parameter and have the method internally update it instead of allocating a new one each time.
如果您只是返回一组“代码”,那么构造结构类型并返回它可能更有意义。在这种情况下,我倾向于将其作为out参数传递,并让方法在内部更新它,而不是每次都分配一个新的。
Are you planning on doing this once or many times?
你打算一次或多次这样做吗?
#2
I know this doesn't really answer your question, but...
我知道这并没有真正回答你的问题,但......
In C++ you should use exceptions instead of returning error codes. Error codes are most commonly used by libraries which don't want to force the library user to use a particular error handling convention, but in C++, we already have stdexcept. Of course, there might be reasons you don't use exceptions, such as if you're writing embedded code or kernel extensions.
在C ++中,您应该使用异常而不是返回错误代码。错误代码最常用于不希望强制库用户使用特定错误处理约定的库,但在C ++中,我们已经有了stdexcept。当然,可能有理由不使用异常,例如,如果您正在编写嵌入式代码或内核扩展。
#3
I usually use a boost::tuple
:
我通常使用boost :: tuple:
typedef boost::tuple<int,int> return_value;
return_value r = my_function();
int first_value = boost::get<0>( r );
int second_valud = boost::get<1>( r );
EDIT
You can also use boost::tie
to extract the values from a tuple:
您还可以使用boost :: tie从元组中提取值:
boost::tie( first_value, second_value ) = r;
#4
The simplest way to return two values is with the std::pair<> template:
返回两个值的最简单方法是使用std :: pair <>模板:
#5
You need to return them as output parameters:
您需要将它们作为输出参数返回:
bool function(int& error1, int& error2, stringx& errorText, int& error3);
#6
You can use an integer with bit manipulation (aka flags).
您可以使用带位操作的整数(也称为标志)。
#7
I would use a bitset if you're intention is to purely return error states. e.g.
如果你的目的是纯粹返回错误状态,我会使用bitset。例如
const bitset<10> a_not_set(1);
const bitset<10> b_not_set(2);
const bitset<10> c_not_set(4);
...
bitset<10> foo(T& a, T& b, T& c, ...)
{
bitset<10> error_code = 0;
...
if ( /* a can't be set */ )
{
error_code |= a_not_set;
}
...
if ( /* b can't be set */ )
{
error_code |= b_not_set;
}
...
// etc etc
return error_code;
}
bitset<10> err = foo(a, b, c, ... );
if (err && a_not_set)
{
// Blah.
}
#8
I probably try to throw an exception first but it depends on your coding paradigm. Please check some books or articles about reasons why c++ exception handling might be better.
我可能首先尝试抛出异常,但这取决于您的编码范例。请查看一些有关c ++异常处理可能更好的原因的书籍或文章。
If I really need to stick to retrun-error-code style, I would define a eunm type for specifying errors with bit operations..
如果我真的需要坚持retrun-error-code风格,我会定义一个eunm类型来指定位操作的错误。
enum error
{
NO_ERROR = 0,
MEMBER_0_NOT_SAVED = 1,
MEMBER_1_NOT_SAVED = 1 << 1,
MEMBER_2_NOT_SAVED = 1 << 2,
// etc..
};
int save()
{
int ret = NO_ERROR;
// fail to save member_0
ret |= MEMBER_0_NOT_SAVED;
// fail to save member_1
ret |= MEMBER_1_NOT_SAVED;
// ....
return ret;
}
int main(void)
{
int ret = save();
if( ret == NO_ERROR)
{
// good.
}
else
{
if(ret & MEMBER_0_NOT_SAVED)
{
// do something
}
if(ret & MEMBER_1_NOT_SAVED)
{
// do something
}
// check the other errors...
}
}
This is just a rough example. It's better to put this into a class or use a namespace.
这只是一个粗略的例子。最好将它放入类或使用命名空间。
#9
I am not familiar with the internals and constrains of your project, but if possible, try to use exceptions instead of error codes.
我不熟悉项目的内部和约束,但如果可能的话,尝试使用异常而不是错误代码。
The reasons are listed here, at C++ FAQ lite, and they conclude with:
这里列出的原因是C ++ FAQ lite,它们总结如下:
So compared to error reporting via return-codes and if, using try / catch / throw is likely to result in code that has fewer bugs, is less expensive to develop, and has faster time-to-market.
因此,与通过返回代码进行错误报告相比,如果使用try / catch / throw可能会导致代码具有更少的错误,开发成本更低,并且具有更快的上市时间。
#1
You can either return an object that has multiple error fields or you can use 'out'parameters.
您可以返回具有多个错误字段的对象,也可以使用“out”参数。
How you do this depends on your design and what exactly you are trying to return back. A common scenario is when you need to report back a status code along with a message of sorts. This is sometimes done where the function returns the status code as the return value and then returns the message status via an 'out' parameter.
你如何做到这一点取决于你的设计以及你想要返回的确切内容。常见的情况是,您需要报告状态代码以及各种消息。有时会在函数返回状态代码作为返回值的情况下执行此操作,然后通过“out”参数返回消息状态。
If you are simply returning a set of 'codes', it might make more sense to construct a struct type and return that. In that case, I would be prone to pass it in as an out parameter and have the method internally update it instead of allocating a new one each time.
如果您只是返回一组“代码”,那么构造结构类型并返回它可能更有意义。在这种情况下,我倾向于将其作为out参数传递,并让方法在内部更新它,而不是每次都分配一个新的。
Are you planning on doing this once or many times?
你打算一次或多次这样做吗?
#2
I know this doesn't really answer your question, but...
我知道这并没有真正回答你的问题,但......
In C++ you should use exceptions instead of returning error codes. Error codes are most commonly used by libraries which don't want to force the library user to use a particular error handling convention, but in C++, we already have stdexcept. Of course, there might be reasons you don't use exceptions, such as if you're writing embedded code or kernel extensions.
在C ++中,您应该使用异常而不是返回错误代码。错误代码最常用于不希望强制库用户使用特定错误处理约定的库,但在C ++中,我们已经有了stdexcept。当然,可能有理由不使用异常,例如,如果您正在编写嵌入式代码或内核扩展。
#3
I usually use a boost::tuple
:
我通常使用boost :: tuple:
typedef boost::tuple<int,int> return_value;
return_value r = my_function();
int first_value = boost::get<0>( r );
int second_valud = boost::get<1>( r );
EDIT
You can also use boost::tie
to extract the values from a tuple:
您还可以使用boost :: tie从元组中提取值:
boost::tie( first_value, second_value ) = r;
#4
The simplest way to return two values is with the std::pair<> template:
返回两个值的最简单方法是使用std :: pair <>模板:
#5
You need to return them as output parameters:
您需要将它们作为输出参数返回:
bool function(int& error1, int& error2, stringx& errorText, int& error3);
#6
You can use an integer with bit manipulation (aka flags).
您可以使用带位操作的整数(也称为标志)。
#7
I would use a bitset if you're intention is to purely return error states. e.g.
如果你的目的是纯粹返回错误状态,我会使用bitset。例如
const bitset<10> a_not_set(1);
const bitset<10> b_not_set(2);
const bitset<10> c_not_set(4);
...
bitset<10> foo(T& a, T& b, T& c, ...)
{
bitset<10> error_code = 0;
...
if ( /* a can't be set */ )
{
error_code |= a_not_set;
}
...
if ( /* b can't be set */ )
{
error_code |= b_not_set;
}
...
// etc etc
return error_code;
}
bitset<10> err = foo(a, b, c, ... );
if (err && a_not_set)
{
// Blah.
}
#8
I probably try to throw an exception first but it depends on your coding paradigm. Please check some books or articles about reasons why c++ exception handling might be better.
我可能首先尝试抛出异常,但这取决于您的编码范例。请查看一些有关c ++异常处理可能更好的原因的书籍或文章。
If I really need to stick to retrun-error-code style, I would define a eunm type for specifying errors with bit operations..
如果我真的需要坚持retrun-error-code风格,我会定义一个eunm类型来指定位操作的错误。
enum error
{
NO_ERROR = 0,
MEMBER_0_NOT_SAVED = 1,
MEMBER_1_NOT_SAVED = 1 << 1,
MEMBER_2_NOT_SAVED = 1 << 2,
// etc..
};
int save()
{
int ret = NO_ERROR;
// fail to save member_0
ret |= MEMBER_0_NOT_SAVED;
// fail to save member_1
ret |= MEMBER_1_NOT_SAVED;
// ....
return ret;
}
int main(void)
{
int ret = save();
if( ret == NO_ERROR)
{
// good.
}
else
{
if(ret & MEMBER_0_NOT_SAVED)
{
// do something
}
if(ret & MEMBER_1_NOT_SAVED)
{
// do something
}
// check the other errors...
}
}
This is just a rough example. It's better to put this into a class or use a namespace.
这只是一个粗略的例子。最好将它放入类或使用命名空间。
#9
I am not familiar with the internals and constrains of your project, but if possible, try to use exceptions instead of error codes.
我不熟悉项目的内部和约束,但如果可能的话,尝试使用异常而不是错误代码。
The reasons are listed here, at C++ FAQ lite, and they conclude with:
这里列出的原因是C ++ FAQ lite,它们总结如下:
So compared to error reporting via return-codes and if, using try / catch / throw is likely to result in code that has fewer bugs, is less expensive to develop, and has faster time-to-market.
因此,与通过返回代码进行错误报告相比,如果使用try / catch / throw可能会导致代码具有更少的错误,开发成本更低,并且具有更快的上市时间。