跳转到内容

更多 C++ 习语/命名循环

来自维基教科书,开放的书籍,开放的世界

命名循环

[编辑 | 编辑源代码]

部分模拟其他语言中找到的标记循环功能。

也称为

[编辑 | 编辑源代码]

标记循环

一些语言,如 Java 和 Perl,支持标记循环结构。在这些语言中,breakcontinue 关键字可以选择指定先前定义的循环标签来控制程序的流程。标记中断将控制流从指定的循环中带出,类似地,标记继续从下一次迭代开始。标签允许中断和继续不仅是最内层的循环,而且任何带有标签的外部循环。标记中断和继续可以提高使用嵌套循环的复杂代码的可读性和灵活性。C++ 中的命名循环习语为该功能提供了部分支持。

解决方案和示例代码

[编辑 | 编辑源代码]

命名循环习语使用 goto 实现。宏用于隐藏 goto 的显式使用,这通常是被人不齿的。只有标记中断语句可以使用以下两个参数化宏来模拟。

#define named(blockname) goto blockname; \
                         blockname##_skip: if (0) \
                         blockname:

#define break(blockname) goto blockname##_skip

named(X) 宏定义了两个 goto 标签 XX_skip。break 宏是一个简单的 goto 到 X_skip 标签。示例如下。

struct test
{
  std::string str;
  test (std::string s) : str(s) { 
    std::cout << "test::test()::" << str << "\n"; 
  }
  ~test () { 
    std::cout << "~test::" << str << "\n"; 
  }
};

int main(void)
{
  named (outer) 
  for (int i = 0; i < 10; i++)
  {
    test t1("t1");
    int j = 0;
    named(inner)
    for (test t2("t2"); j < 5; j++)
    {
      test t3("t3");
      if (j == 1) break(outer);
      if (j == 3) break(inner);
      test t4("t4");
    }
    std::cout << "after inner\n";
  }
  return 0;
}

goto 不影响对象的正确构造和销毁,如上述程序的输出所证实。

test::test()::t1

test::test()::t2

test::test()::t3

test::test()::t4

~test::t4

~test::t3

test::test()::t3

~test::t3

~test::t2

~test::t1

已知用法

[编辑 | 编辑源代码]
[编辑 | 编辑源代码]

参考文献

[编辑 | 编辑源代码]
华夏公益教科书