在以前,若是我們要針對 STL container 中的所有物件做事情,最「方便」的方法是使用 iterator 搭配傳統的 for-loop:
class Entry;
list<Entry> my_list;
void check_entries(void)
{
for ( list::iterator<Entry> itor = my_list.begin(); itor != my_list.end(); ++itor)
{
Entry& e = *itor; // iterator 本身的操作類似 pointer
// do something...
}
}
那行 for
的敘述式真是又臭又長。即使是 C++11 導入了 auto
關鍵字,可以用來取代 itor
前面的型別,整體的可讀性還是很差。
幸好,C++11 同時導入了其他高階語言常見的 ranged for-loop,可以增加可讀性,也不用再 key 那麼多囉嗦的程式碼了:
void check_entries(void)
{
for ( auto& e : my_list)
{
// do something...
}
}
使用上有幾個需要注意的地方:
- 元素
e
的作用範圍 (scope) 僅在 for-loop 中。出了 for-loop 就不能用了(這是優點)。 - 若是型別的後面沒有 reference 符號
&
,那麼e
就是「複製出來」的物件,類似 C/C++ 中 call by value 的概念。此時e
是不能修改的(或者說:就算修改了,也不會影響到my_list
中對應物件的內容)。若是需要修改,就要加上&
。 - 加上
&
還有一個優點,那就是不需要複製整個物件。這對於占用空間較大的物件(通常是使用者定義的 class 生出來的物件)來說比較有效率。 - 若是需要效率,又希望保有「唯讀」的特性,可以在型別前面加上
const
。以此例來說,就是變成:for (const auto& e : my_list)
。