更多 C++ 習語/命名迴圈
外觀
部分模擬其他語言中找到的標記迴圈功能。
標記迴圈
一些語言,如 Java 和 Perl,支援標記迴圈結構。在這些語言中,break 和 continue 關鍵字可以選擇指定先前定義的迴圈標籤來控制程式的流程。標記中斷將控制流從指定的迴圈中帶出,類似地,標記繼續從下一次迭代開始。標籤允許中斷和繼續不僅是最內層的迴圈,而且任何帶有標籤的外部迴圈。標記中斷和繼續可以提高使用巢狀迴圈的複雜程式碼的可讀性和靈活性。C++ 中的命名迴圈習語為該功能提供了部分支援。
命名迴圈習語使用 goto 實現。宏用於隱藏 goto 的顯式使用,這通常是被人不齒的。只有標記中斷語句可以使用以下兩個引數化宏來模擬。
#define named(blockname) goto blockname; \
blockname##_skip: if (0) \
blockname:
#define break(blockname) goto blockname##_skip
named(X) 宏定義了兩個 goto 標籤 X 和 X_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