C++11 前無標準 foreach,但可用宏模擬。本文提供 VC (MSVC) 與 GCC 兩大編譯器的最簡實現,性能與手寫迭代器幾乎無差。
std::vector<int> vec = {1,2,3};
foreach(int i, vec) { std::cout << i; }
MSVC 早期即支援 for each 關鍵字 (非標準擴充),直接映射:
#define foreach(var, container) for each(var in container)
支援所有實作 begin/end 或 MFC 集合的類型。
GCC 支援 typeof (C++11 後為 decltype),結合 __extension__ 實現單語句 for 迴圈結構:
template <typename C>
struct foreach_helper {
typename C::const_iterator it, end;
foreach_helper(const C& c) : it(c.begin()), end(c.end()) {}
};
#define RANDOM_VAR(name, line) RANDOM_VAR_(name, line)
#define RANDOM_VAR_(name, line) name##line
#define foreach(var, container) \
__typeof__(container) const& RANDOM_VAR(_con_, __LINE__) = container; \
for (foreach_helper<__typeof__(container)> _fh_(RANDOM_VAR(_con_, __LINE__)); \
_fh_.it != _fh_.end; ++_fh_.it) \
for (var = *_fh_.it;; __extension__ ({ break; }))
const& _con_ = container 綁定臨時物件 (如函數返回值),引用延長其壽命至迴圈結束。var = *_fh_.it,__extension__({break;}) 確保內層只跑一次。__LINE__ 避免巢狀迴圈變數衝突。| 編譯器 | foreach 宏 | 手寫迭代器 | 備註 |
|---|---|---|---|
| GCC | ~1.0x | 1.0x (基準) | 幾乎無損耗 |
| VC9 (VS2008) | ~5.0x | 1.0x | VC 迭代器優化較弱,foreach 宏映射到原生 for each 效能較差 |
結論:GCC 版本零開銷;VC 建議直接寫原生 for each 或 C++11 範圍 for。
const_iterator、begin()/end()。