我读过一篇关于 C++ 中的“命名循环惯用法”的文章:http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Named_Loop http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Named_Loop
这个习语允许我们写这样的东西:
named(outer)
for(int i = 0 ; i < rows ; ++i) {
named(inner)
for(int j = 0 ; j < cols ; ++j) {
if(some_condition)
break(outer); // exit the 'outer' loop
}
}
这种结构已经作为许多语言的核心特性存在,例如 Java。
根据文章,它可以通过定义两个邪恶的宏在 C++ 中实现:
#define named(blockname) goto blockname; \
blockname##_skip: if (0) \
blockname:
#define break(blockname) goto blockname##_skip;
我知道很多人想禁止使用goto
。我个人发现它在极少数情况下很有帮助,特别是当我想要break
一堆嵌套循环。在我看来,这个习惯用法是一个更干净的解决方案,但是在实际代码中使用它可以吗?
在文章的讨论页面上,可以看到:
“不要这样做。你最终会下地狱”
所以我的问题是:使用命名循环习惯用法有哪些缺点?危险吗 ?如果是,为什么?
额外问题:是否可以实现命名continue
相似地 ? (我认为不可能使用named(...) for(...;...;...) {}
语法,但谁知道呢?)
编辑:我同意你的观点,重新定义关键字是令人讨厌的。使用怎么样#define breakLoop()
反而?
正如评论中所述,#definingbreak
是有问题的。假设您使用其他东西。
我仍然认为这很危险。这是一个极其不寻常的习惯用法(对于 C++ 程序员来说),因此他们不太可能理解,因此他们可能会做出重大更改。鉴于有一些不那么令人惊讶,因此也不那么危险的方法来完成同样的事情,我建议不要这样做。
考虑将循环放入函数或 lambda 中。然后你可以return
打破外循环。好处是,您可以返回有关过早退出的信息,这可能对外部代码有用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)