是否有相当于C++中的"for ... else"Python循环?

Del*_*gan 61 c++ python loops for-loop break

Python有一个有趣的for语句,允许您指定一个else子句.

在像这样的结构中:

for i in foo:
  if bar(i):
    break
else:
  baz()
Run Code Online (Sandbox Code Playgroud)

else子句在之后执行for,但仅在for正常终止时(不是由a break)终止.

我想知道C++中是否有相同的东西?我可以用for ... else吗?

Ton*_*roy 34

表达实际逻辑的更简单方法是std::none_of:

if (std::none_of(std::begin(foo), std::end(foo), bar))
    baz();
Run Code Online (Sandbox Code Playgroud)

如果接受C++ 17的范围提议,希望这将简化为:

if (std::none_of(foo, bar)) baz();
Run Code Online (Sandbox Code Playgroud)

  • 不完全等同.例如,它不允许通过"条"修改容器的元素.更不用说,它让我(一个C++开发者)在帮助中查找它,而原始的OP python示例我没有立即理解的问题.stl变成泥堆. (10认同)
  • 我指的是这里的帮助页面:http://www.cplusplus.com/reference/algorithm/none_of/ 或这里 http://en.cppreference.com/w/cpp/algorithm/all_any_none_of。两者都说谓词不应修改参数。 (2认同)

ify*_*ner 24

如果不介意使用goto也可以通过以下方式完成.这个节省了额外的if检查和更高范围的变量声明.

for(int i = 0; i < foo; i++)
     if(bar(i))
         goto m_label;
baz();

m_label:
...
Run Code Online (Sandbox Code Playgroud)

  • @MatthiasB我也不认为'goto'已经过时了.因为仍有一些字段需要省略额外的"if"检查和性能和内存注意事项的声明,同时仍然使用C++编程. (5认同)
  • 如果我们考虑语言等效性,那么这是唯一有效的答案.Python没有,而C++和其他所有示例,例如使用return,临时变量和break,或者异常都可以用Python完成.另外,这种情况(for else)以及打破嵌套循环可能是C++中goto的有效应用程序的两种情况. (4认同)
  • goto是明确定义的,通常是复杂循环处理的最易理解(即最佳可维护)解决方案.这个解决方案有我的投票(我会给出类似的一个). (4认同)
  • 转到部分并不是那么糟糕.这就是我在这种情况下使用的.我认为它实际上比基于标志的解决方案更具可读性. (3认同)
  • @MatthiasB据我所知,问题不是关于使用什么,而是关于C++中可能的实现. (2认同)

hac*_*cks 13

是的,你可以通过以下方式达到同样的效

auto it = std::begin(foo);
for (; it != std::end(foo); ++it)
     if(bar(*it))
         break;
if(it == std::end(foo))
    baz();
Run Code Online (Sandbox Code Playgroud)

  • 不,Python循环根本不算数.`i`可能永远不会是整数.它更像是C++ 11`(auto i:foo)`. (3认同)
  • `for(auto it = begin(something); it!= end(something); ++ i)`... if(it == end(something))`...另外请记住,每次你做postfix增量不必要,一只小猫死了. (3认同)
  • 请注意,当Python循环遍历可迭代foo的元素时,这会从0到foo计数.虽然可能很容易调整(比较`end()`). (2认同)

Eas*_*ton 11

这是我在C++中的粗略实现:

bool other = true;
for (int i = 0; i > foo; i++) {
     if (bar[i] == 7) {
          other = false;
          break;
     }
} if(other)
     baz();
Run Code Online (Sandbox Code Playgroud)

  • 为什么`i> foo`?不应该是`我<foo`? (3认同)
  • +1 因为我认为这个解决方案最清楚地说明了意图。 (2认同)

Noa*_*ack 10

您可以使用lambda函数:

[&](){
  for (auto i : foo) {
    if (bar(i)) {
      // early return, to skip the "else:" section.
      return;
    }
  }
  // foo is exhausted, with no item satisfying bar(). i.e., "else:"
  baz();
}();
Run Code Online (Sandbox Code Playgroud)

这应该与Python的"for..else"完全相同,并且与其他解决方案相比具有一些优势:

  • 它是"for..else"的真正替代品:"for"部分可能有副作用(与none_of不同,其谓词不得修改其参数),并且它可以访问外部作用域.
  • 它比定义特殊宏更具可读性.
  • 它不需要任何特殊的标志变量.

但是......我会使用笨重的旗帜变量,我自己.