跳至內容

More C++ Idioms/循環命名

維基教科書,自由的教學讀本

循環命名

[編輯]

意圖

[編輯]

部分仿真其他語言中的循環標籤特性

別名

[編輯]
  • Labeled loop
  • Named loop

動機

[編輯]

像 Java,Perl這些語言支持循環的命名,在這些語言中,breakcontinue關鍵字可以選擇指定一個先前定義的循環標籤來控制程序的流程。帶標籤的break將控制流跳出指定的循環,同樣的帶標籤的continue將在指定的循環處開始下一次迭代。標籤允許break 和 continue不只是跳出或繼續最內層的循環,而是可以跳出任何外部的帶有標籤的循環。帶有標籤的 break 和 continue 能夠增加具有嵌套循環的代碼可讀性和可變性。C++ 中的命名循環原語部分支持這一特性。

解決方案和示例代碼

[編輯]

命名循環原語用goto來實現。用宏來隱藏goto的顯式使用。用下面的代碼就可以仿真帶標籤的break語句:

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

#define break(blockname) goto blockname##_skip;

named(X) 定義了兩個 goto 標籤 XX_skip。 break 宏只是簡單的跳轉到 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

已知應用

[編輯]

相關原語

[編輯]

參考資料

[編輯]