迴圈通過一個容器

在 C++中,迴圈遍歷序列容器 c 可以使用索引完成,如下所示:

for(size_t i = 0; i < c.size(); ++i) c[i] = 0;

雖然簡單,但是這些著作會遇到常見的語義錯誤,例如錯誤的比較運算子或錯誤的索引變數:

for(size_t i = 0; i <= c.size(); ++j) c[i] = 0;
                     ^~~~~~~~~~~~~~^

使用迭代器的所有容器也可以實現迴圈,具有類似的缺點:

for(iterator it = c.begin(); it != c.end(); ++it) (*it) = 0;

C++ 11 引入了基於範圍的 for 迴圈和 auto 關鍵字,允許程式碼變為:

for(auto& x : c) x = 0;

這裡唯一的引數是容器 c,以及一個變數 x 來儲存當前值。這可以防止先前指出的語義錯誤。

根據 C++ 11 標準,底層實現相當於:

for(auto begin = c.begin(), end = c.end(); begin != end; ++begin)
{
    // ...
}

在這種實現中,表示式 auto begin = c.begin(), end = c.end(); 強制 beginend 屬於同一型別,而 end 永遠不會增加,也不會被解除引用。因此,基於範圍的 for 迴圈僅適用於由迭代器/迭代器對定義的容器。C++ 17 標準通過將實現更改為:來放寬此約束:

auto begin = c.begin();
auto end = c.end();
for(; begin != end; ++begin)
{
    // ...
}

在這裡,beginend 可以是不同型別的,只要它們可以比較不相等。這允許迴圈通過更多容器,例如由對迭代器/哨兵定義的容器。