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

函式物件完整指南:從基本定義到 STL 謂詞與樣板化實戰

     編輯:關於C++

什麼是函式物件?

函式物件(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
}

單一函式物件支援任意可取負運算的型別,函式指標難以達到同等彈性。

STL 內建函式物件:<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 組合出複雜條件。

函式物件 vs 函式指標 vs Lambda (C++11)

特性函式指標函式物件Lambda
狀態保存困難(全域/靜態)自然(資料成員)捕獲列表
內聯優化極難容易容易
型別通用單一簽章樣板化支援auto + 樣板
語法簡潔度中較繁瑣最高
適用場景C API 回呼、動態載入STL 算法、狀態演算、策略模式短小內聯邏輯、臨時回呼

總結

函式物件是 C++ 「物件即函式」哲學的體現。它以類別封裝狀態、運算子重載實現呼叫語法、樣板實現型別通用、內聯優化效能,完美契合 STL 算法框架。雖然 C++11 Lambda 大幅簡化短小邏輯撰寫,但函式物件在複雜狀態管理、可重用策略封裝、編譯期型別計算等場景仍具不可替代價值。

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