迴圈通過一個容器
在 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();
強制 begin
和 end
屬於同一型別,而 end
永遠不會增加,也不會被解除引用。因此,基於範圍的 for 迴圈僅適用於由迭代器/迭代器對定義的容器。C++ 17 標準通過將實現更改為:來放寬此約束:
auto begin = c.begin();
auto end = c.end();
for(; begin != end; ++begin)
{
// ...
}
在這裡,begin
和 end
可以是不同型別的,只要它們可以比較不相等。這允許迴圈通過更多容器,例如由對迭代器/哨兵定義的容器。