// 回呼函數
inline bool compare(int a, int b) { return a > b; }
// 仿函數
struct comparer {
bool operator()(int a, int b) const { return a > b; }
};
// 使用
std::sort(vec.begin(), vec.end(), compare); // 函數指標
std::sort(vec2.begin(), vec2.end(), comparer()); // 仿函數物件
void* 參數傳遞上下文,介面更乾淨。std::sort) 非內聯/遞迴無法展開,回呼函數以函數指標傳入,**無法內聯**,每次比較皆為間接呼叫。operator() **內聯** 展開至演算法迴圈中,消除呼叫開銷。對 std::sort 這類比較次數極多 (O(n log n)) 的演算法,內聯帶來的效能提升呈雪崩式放大。std::AutoFreeAlloc 存放異質解構函數)。模板仿函數型別固定,無法像函數指標那樣型別抹除。void (*)(void*) 時。dlsym/GetProcAddress 取得函數指標。| 場景 | 推薦 | 理由 |
|---|---|---|
標準演算法 (sort, find_if 等) | 仿函數 / Lambda | 內聯優化、型別安全、可攜帶狀態 |
| 需儲存異質可呼叫物件 | std::function / 函數指標 | 型別抹除、統一介面 |
| C API 回呼 | 函數指標 | ABI 相容 |
| 簡單無狀態邏輯 | Lambda (C++11+) | 就地定義、自動推導型別、可捕獲變數 |
C++11 起,Lambda 表達式 取代絕大多數手寫仿函數場景:
std::sort(v.begin(), v.end(), [](int a, int b){ return a > b; });
需要攜帶狀態時:
int threshold = 10;
std::copy_if(v.begin(), v.end(), out, [threshold](int x){ return x > threshold; });
僅在需要型別抹除 (存入容器、跨 DLL 介面) 時使用 std::function。