函式物件(Function Object,又稱 Functor)是重載 operator() 的類別實例。語法上像函式,實為物件,兼具狀態保存與內聯優化優勢。
class Negate {
public:
int operator()(int n) { return -n; } // 重載 ()
};
void Callback(int n, Negate& neg) {
int val = neg(n); // 像呼叫函式,實為 neg.operator()(n)
std::cout << val;
}
int main() {
Callback(5, Negate()); // 輸出 -5,傳遞臨時物件
}
() 為運算子名稱(固定空),第二個為參數列。operator(),消除呼叫開銷(函式指標幾乎無法內聯)。函式物件可擁有資料成員,儲存先前呼叫結果或配置狀態:
class Accumulator {
int sum_ = 0;
public:
int operator()(int n) { return sum_ += n; }
};
Accumulator acc;
acc(10); // 10
acc(20); // 30
acc(5); // 35
以函式指標實現需用全域/靜態變數,帶來執行緒安全、封裝性差等問題。
class GenericNegate {
public:
template
T operator()(T t) const { return -t; }
};
int main() {
GenericNegate neg;
std::cout << neg(5.3333); // double: -5.3333
std::cout << neg(10000000000i64); // __int64
}
單一函式物件支援任意可取負運算的型別,函式指標難以達到同等彈性。
<functional> 謂詞標準庫提供常用函式物件,可直接用於算法:
#include
#include
#include
int main() {
std::vector vi = {5, 2, 8, 1, 9};
std::sort(vi.begin(), vi.end(), std::greater()); // 降序:9 8 5 2 1
std::sort(vi.begin(), vi.end(), std::less()); // 升序:1 2 5 8 9
}
std::greater、std::less:二元謂詞,回傳 bool。equal_to, not_equal_to, logical_and, plus, multiplies 等。std::bind、std::not1 組合出複雜條件。| 特性 | 函式指標 | 函式物件 | Lambda |
|---|---|---|---|
| 狀態保存 | 困難(全域/靜態) | 自然(資料成員) | 捕獲列表 |
| 內聯優化 | 極難 | 容易 | 容易 |
| 型別通用 | 單一簽章 | 樣板化支援 | auto + 樣板 |
| 語法簡潔度 | 中 | 較繁瑣 | 最高 |
| 適用場景 | C API 回呼、動態載入 | STL 算法、狀態演算、策略模式 | 短小內聯邏輯、臨時回呼 |
函式物件是 C++ 「物件即函式」哲學的體現。它以類別封裝狀態、運算子重載實現呼叫語法、樣板實現型別通用、內聯優化效能,完美契合 STL 算法框架。雖然 C++11 Lambda 大幅簡化短小邏輯撰寫,但函式物件在複雜狀態管理、可重用策略封裝、編譯期型別計算等場景仍具不可替代價值。