Ada*_*m S -5 c++ error-handling goto
假设我想连续调用四个函数,这些函数在我的某个对象上运行.如果其中任何一个失败,我想返回FAILURE而不调用其他人,我想要返回SUCCESSiff所有这些都成功完成.
通常,我会做这样的事情:
if(function_zero(&myMutableObject) == SUCCESS)
{
return FAILURE;
}
if(function_one(&myMutableObject) == SUCCESS)
{
return FAILURE;
}
if(function_two(&myMutableObject) == SUCCESS)
{
return FAILURE;
}
if(function_three(&myMutableObject) == SUCCESS)
{
return FAILURE;
}
return SUCCESS;
Run Code Online (Sandbox Code Playgroud)
或者,如果我需要做一些清理:
if(function_zero(&myMutableObject) == SUCCESS)
{
status = FAILURE;
goto cleanup;
}
if(function_one(&myMutableObject) == SUCCESS)
{
status = FAILURE;
goto cleanup;
}
if(function_two(&myMutableObject) == SUCCESS)
{
status = FAILURE;
goto cleanup;
}
if(function_three(&myMutableObject) == SUCCESS)
{
status = FAILURE;
goto cleanup;
}
cleanup:
// necessary cleanup here
return status;
Run Code Online (Sandbox Code Playgroud)
但是,我正在进行的项目有一些限制:
goto,永远这导致我这样的事情:
if(function_zero(&myMutableObject) == SUCCESS)
{
if(function_one(&myMutableObject) == SUCCESS)
{
if(function_two(&myMutableObject) == SUCCESS)
{
status = function_three(&myMutableObject);
}
else
{
status = FAILURE;
}
}
else
{
status = FAILURE;
}
}
else
{
status = FAILURE;
}
return status;
Run Code Online (Sandbox Code Playgroud)
不幸的是,这使我经常违反行长限制.
我的问题是:有没有更简单的方法来写这个?
注意事项和限制:
使用例外和RAII.这些都是他们发明要解决的问题.例外情况更多的是系统范围的功能,而不是您可以在本地应用的功能.
对于清理块,RAII正是您需要的功能.
对于成功/失败,我们可以使用lambdas和variadics隐式链接它们.
现在我们可以简单地将它们写成列表中的lambda.
status f() {
struct nested {
static template<typename F> status_t Check(F f) {
return f();
}
static template<typename F, typename... Chain> status_t Check(F f, Chain... chain) {
auto status = f();
return status != failure ? Check(chain...) : status;
}
};
return nested::Check(
[] { return function_zero(&myMutableObject); },
[] { return function_one(&myMutableObject); },
[] { return function_two(&myMutableObject); },
[] { return function_three(&myMutableObject); },
);
}
Run Code Online (Sandbox Code Playgroud)
如果你需要捕获返回值,这会变得有点问题,但由于它似乎总是带有out参数的错误代码,如果你只是声明接收变量f(),那么应该没问题,那么所有未来的lambdas都可以引用它.它也不要求每个函数具有相同的签名或分配各种数据结构.
仅当状态当前使用&&运算符设置为SUCCESS时才调用测试.如果设置为FAILURE,&&将立即失败,后续测试将不会执行.
status = SUCCESS
if (status == SUCCESS && function_zero(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
if (status == SUCCESS && function_one(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
if (status == SUCCESS && function_two(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
if (status == SUCCESS && function_three(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
return status;
Run Code Online (Sandbox Code Playgroud)
正如@Mooing Duck建议的那样,你可以简单地在else if链中完成所有操作:
status = SUCCESS
if (function_zero(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
else if (function_one(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
else if (function_two(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
else if (function_three(&myMutableObject) == FAILURE)
{
status = FAILURE;
}
return status;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
528 次 |
| 最近记录: |