【问题标题】:Concise way to write a for/else in C++?在 C++ 中编写 for/else 的简洁方法?
【发布时间】:2014-10-02 05:21:44
【问题描述】:

在我正在处理的一些代码中,我有一个遍历地图的 for 循环:

for (auto it = map.begin(); it != map.end(); ++it) {

    //do stuff here
}

我想知道是否有某种方法可以简洁地写出以下内容:

for (auto it = map.begin(); it != map.end(); ++it) {
    //do stuff here
} else {
    //Do something here since it was already equal to map.end()
}

我知道我可以重写为:

auto it = map.begin();
if (it != map.end(){

    while ( it != map.end() ){
        //do stuff here
        ++it;
    }

} else {
    //stuff
}

但是有没有更好的方法不涉及包装在 if 语句中?

【问题讨论】:

  • 请问for() {} else {} 是什么?!?
  • 不,如果没有某种条件包装器,就没有办法做到这一点。
  • 这是一个python和其他语言的语句,可以让你指定当循环没有被执行时会发生什么。
  • 你的意思是Python风格的for else
  • 我认为这样的事情曾经提出过。

标签: c++ c++11 for-loop for-else


【解决方案1】:

显然……

if (map.empty())
{
    // do stuff if map is empty
}
else for (auto it = map.begin(); it != map.end(); ++it)
{
    // do iteration on stuff if it is not
}

顺便说一句,由于我们在这里讨论的是 C++11,所以您可以使用以下语法:

if (map.empty())
{
    // do stuff if map is empty
}
else for (auto it : map)
{
    // do iteration on stuff if it is not
}

【讨论】:

  • 不过,一般来说,对于没有 .empty() 的对象,有没有更简洁的 for-else 方法?
  • if (map.begin() == map.end())
  • template<class R>bool empty(R const& r){using std::begin; using std::end; return begin(r)==end(r);} 是一个适用于所有可迭代范围的.empty()
  • 这个else for-condensed-into-one-line 真的是人们所熟悉的吗?我的意思是确定它很聪明并且实现了它的目的,但我不禁想知道它是否被识别到足以像下一行缩进的 for 一样可读。
  • 这与 Python else 不同,因为它在容器为空或已被完全遍历时执行。它唯一不执行的是break 语句。见:docs.python.org/3.4/tutorial/…
【解决方案2】:

如果你想在 C++ 中更疯狂的控制流,你可以用 C++11 来写:

template<class R>bool empty(R const& r)
{
  using std::begin; using std::end;
  return begin(r)==end(r);
}
template<class Container, class Body, class Else>
void for_else( Container&& c, Body&& b, Else&& e ) {
  if (empty(c)) std::forward<Else>(e)();
  else for ( auto&& i : std::forward<Container>(c) )
    b(std::forward<decltype(i)>(i));
}

for_else( map, [&](auto&& i) {
  // loop body
}, [&]{
  // else body
});

但我建议不要这样做。

【讨论】:

    【解决方案3】:

    Havenard's else for 的启发,我尝试了这种结构,其中else 部分位于正确的位置[1]

    if (!items.empty()) for (auto i: items) {
        cout << i << endl;
    } else {
        cout << "else" << endl;
    }
    

    (full demo)

    我不确定我是否会在实际代码中使用它,还因为我不记得有一个案例是我在 for 循环中缺少一个 else 子句,但我不得不承认只有今天我了解到python有它。我从你的评论中读到了

    //Do something here since it was already equal to map.end()
    

    ...您可能指的不是python's for-else,但也许您指的是python programmers seem to have their problems with this feature


    [1] 不幸的是,C++ 中没有 concise opposite of is empty ;-)

    【讨论】:

      猜你喜欢
      • 2014-01-26
      • 2021-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      相关资源
      最近更新 更多