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

C++ mem_fun 與 mem_fun_ref 詳解:將成員函數適配為 STL 算法可調用對象

     編輯:C++ 入門

問題背景

對 vector<A> vec 中每個對象調用成員函數 print()。手寫循環雖可行,但 STL 建議優先使用算法(for_each),原因:效率更高(庫作者優化)、正確性更強(代碼少少錯)、可維護性更好(意圖清晰)。

直接傳遞成員函數指針失敗

for_each(vec.begin(), vec.end(), &A::print); // 編譯錯誤:成員函數指針非可調用對象

mem_fun_ref 解決方案(對象容器)

for_each(vec.begin(), vec.end(), mem_fun_ref(&A::print)); // 正確
  • mem_fun_ref 接受成員函數指針,返回一個函數對象(仿函數)
  • 調用時隱式將容器元素(對象引用)作為 this 傳遞
  • 適用於 vector<T>, list<T> 等存儲對象的容器

mem_fun 解決方案(指針容器)

vector<A*> vec_ptr;
for_each(vec_ptr.begin(), vec_ptr.end(), mem_fun(&A::print)); // 正確
  • mem_fun 返回的函數對象期望接收指針作為 this
  • 適用於 vector<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_refT (對象)(obj.*mem_fn)()[](T& o){ o.mem_fn(); }
mem_funT* (指針)(ptr->*mem_fn)()[](T* p){ p->mem_fn(); }

遺留代碼維護提示

遇到舊代碼中的 mem_fun(_ref),理解其作用即可;新代碼優先用 Lambda,可讀性更強、無需記憶適配器名稱。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved