在这种非常特殊的情况下使用 goto.. 替代方案?
Use of goto in this very specific case... alternatives?
我对在C++代码中可能使用goto
有疑问:我知道应该尽可能避免goto
,但在这种非常特殊的情况下,我很难找到避免使用多个嵌套的 if-else 和/或其他二进制标志的好替代方案...... 代码类似于以下代码(仅报告相关部分):
// ... do initializations, variable declarations, etc...
while(some_flag) {
some_flag=false;
if(some_other_condition) {
// ... do few operations (20 lines of code)
return_flag=foo(input_args); // Function that can find an error, returning false
if(!return_flag) {
// Print error
break; // jump out of the main while loop
}
// ... do other more complex operations
}
index=0;
while(index<=SOME_VALUE) {
// ... do few operations (about 10 lines of code)
return_flag=foo(input_args); // Function that can find an error, returning false
if(!return_flag) {
goto end_here; // <- 'goto' statement
}
// ... do other more complex operations (including some if-else and the possibility to set some_flag to true or leave it to false
// ... get a "value" to be compared with a saved one in order to decide whether to continue looping or not
if(value<savedValue) {
// Do other operations (about 20 lines of code)
some_flag=true;
}
// ... handle 'index'
it++; // Increse number of iterations
}
// ... when going out from the while loop, some other operations must be done, at the moment no matter the value of some_flag
return_flag=foo(input_args);
if(!return_flag) {
goto end_here; // <- 'goto' statement
}
// ... other operations here
// ... get a "value" to be compared with a saved one in order to decide whether to continue looping or not
if(value<savedValue) {
// Do other operations (about 20 lines of code)
some_flag=true;
}
// Additional termination constraint
if(it>MAX_ITERATIONS) {
some_flag=false;
}
end_here:
// The code after end_here checks for some_flag, and executes some operations that must always be done,
// no matter if we arrive here due to 'goto' or due to normal execution.
}
}
// ...
每次foo()
返回false
时,不应再执行任何操作,代码应尽快执行最终操作。另一个要求是,这个代码,主要是while(index<=SOME_VALUE)
内部的部分,应该尽可能快地运行,以尽量有好的整体性能。
使用"try/catch"块,其中try{}
包含大量代码(而实际上,函数foo()只有在调用时才能生成错误,即仅在代码的两个不同点)是一种可能的替代方案?在这种情况下,使用不同的"尝试/捕获"块是否更好? 还有其他更好的选择吗?
提前非常感谢!
三个明显的选择:
-
坚持
goto
-
将清理代码与某些 RAII 类的析构函数相关联。 (您可以将其写为
std::unique_ptr
的删除作为lambda。 -
将函数重命名为
foo_internal
,并将其更改为return
。然后在一个新的foo
函数中编写清理,该函数调用foo_internal
所以:
return_t foo(Args...) {
const auto result = foo_internal(Args..);
// cleanup
return result;
}
通常,您的函数看起来太长,需要分解为较小的位。
一种方法是使用另一个虚拟循环并像这样break
int state = FAIL_STATE;
do {
if(!operation()) {
break;
}
if(!other_operation()) {
break;
}
// ...
state = OK_STATE;
} while(false);
// check for state here and do necessary cleanups
这样,您可以事先避免代码中的深层嵌套级别。
这是C++!对非本地跳转使用例外:
try {
if(some_result() < threshold) throw false;
}
catch(bool) {
handleErrors();
}
// Here follows mandatory cleanup for both sucsesses and failures
相关文章:
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 计算每个节点的树高,帮助我解释这个代码解决方案
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- visual c++,如何获取解决方案目录中的代码
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- C++11 中不同类型的对象的 std::array 的替代方案
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 别名模板的专业化 C++11 中没有开销的最佳替代方案
- 我的固定时间步长与增量时间和插值的解决方案是错误的吗?
- 无法在问题解决方案中执行输出逻辑
- 如何正确指定 goto 语句的标签?
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- ANTLR GOTO statement
- 为什么我的功能在使用 goto 时会给我带来"expected primary-expression before '}' token"?
- 在一个解决方案中针对第三方静态库 (Creo) 的不同版本(版本)进行构建
- 在这种非常特殊的情况下使用 goto.. 替代方案?