首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

跨編譯器實現 foreach 宏:VC 原生支援與 GCC typeof 技巧

     編輯:關於VC++

C++11 前無標準 foreach,但可用宏模擬。本文提供 VC (MSVC) 與 GCC 兩大編譯器的最簡實現,性能與手寫迭代器幾乎無差。

標準用法期望

std::vector<int> vec = {1,2,3};
foreach(int i, vec) { std::cout << i; }

1. Visual C++ 實現 (極簡)

MSVC 早期即支援 for each 關鍵字 (非標準擴充),直接映射:

#define foreach(var, container)  for each(var in container)

支援所有實作 begin/end 或 MFC 集合的類型。

2. GCC 實現 (利用 typeof + 臨時變量延長壽命)

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 綁定臨時物件 (如函數返回值),引用延長其壽命至迴圈結束。
  • 雙層 for 結構:外層迭代,內層單次執行賦值 var = *_fh_.it,__extension__({break;}) 確保內層只跑一次。
  • 隨機變數名:__LINE__ 避免巢狀迴圈變數衝突。

3. 性能實測 (O2 優化)

編譯器foreach 宏手寫迭代器備註
GCC~1.0x1.0x (基準)幾乎無損耗
VC9 (VS2008)~5.0x1.0xVC 迭代器優化較弱,foreach 宏映射到原生 for each 效能較差

結論:GCC 版本零開銷;VC 建議直接寫原生 for each 或 C++11 範圍 for。

適用場景與限制

  • 適用於舊專案無法升級 C++11 但需統一遍歷語法。
  • 不支援修改容器結構 (刪除元素) 需自行處理迭代器失效。
  • GCC 版本需容器提供 const_iterator、begin()/end()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved