對 vector<A> vec 中每個對象調用成員函數 print()。手寫循環雖可行,但 STL 建議優先使用算法(for_each),原因:效率更高(庫作者優化)、正確性更強(代碼少少錯)、可維護性更好(意圖清晰)。
for_each(vec.begin(), vec.end(), &A::print); // 編譯錯誤:成員函數指針非可調用對象
for_each(vec.begin(), vec.end(), mem_fun_ref(&A::print)); // 正確
mem_fun_ref 接受成員函數指針,返回一個函數對象(仿函數)this 傳遞vector<T>, list<T> 等存儲對象的容器vector<A*> vec_ptr; for_each(vec_ptr.begin(), vec_ptr.end(), mem_fun(&A::print)); // 正確
mem_fun 返回的函數對象期望接收指針作為 thisvector<T*>, list<T*> 等存儲指針的容器兩者均為模板函數,返回繼承自 std::unary_function 的適配器類,重載 operator() 內部調用 (obj.*ptr)() 或 (ptr->*ptr)()。C++11 起推薦使用 std::bind 或 Lambda 替代:
for_each(vec.begin(), vec.end(), [](A& a){ a.print(); }); // Lambda 更直觀
for_each(vec_ptr.begin(), vec_ptr.end(), [](A* p){ p->print(); });
| 適配器 | 容器元素類型 | 調用語義 | C++11 替代 |
|---|---|---|---|
| mem_fun_ref | T (對象) | (obj.*mem_fn)() | [](T& o){ o.mem_fn(); } |
| mem_fun | T* (指針) | (ptr->*mem_fn)() | [](T* p){ p->mem_fn(); } |
遇到舊代碼中的 mem_fun(_ref),理解其作用即可;新代碼優先用 Lambda,可讀性更強、無需記憶適配器名稱。