函式物件

函式物件（function object） They are similar to a function object, but not the same.|name=a|group=note}} 是一個程式設計的物件允許被當作普通函式來呼叫。

函式物件與函式指標相比，有兩個優點：第一是編譯器可以內聯執行函式物件的呼叫；第二是函式物件內部可以保持狀態。

函式式程式設計語言還支援閉包，例如，first-class 函式支援在其建立時用到的函式外定義的變數的值保持下來，成為一個函式閉包。

C++ 函式物件的例項

傳統的 C/C++ 函式指標：

include

/ Callback function, returns 0 if a > b, 0 if a == b /

int compareInts (const void a, const void b)

{return (const int ) a - (const int ) b;

}

...

//prototype of qsort is

//void qsort (void base, sizet nel, sizet width, int (compar)(const void , const void ));

...

int main (void)

{int items = { 4, 3, 1, 2};

qsort (items, sizeof (items) /sizeof (items0), sizeof (items0), compareInts);

return 0;

}

C++ 中，函式物件是定義了函式呼叫運算子的類物件，稱作 class type functor。

//comparator predicate: returns true if a

void sort (RandomIt first, RandomIt last, Compare comp);

...

int main

{std::vector items { 4, 3, 1, 2};

std::sort (items.begin , items.end , IntComparator );

return 0;

}

除了類型別函式物件，還有其他型別的函式物件，如使用成員函式指標或模板。C++11 允許使用具有閉包功能的匿名函式。

C++ STL 中的函式物件

C++ 的 STL 中的眾多 algorithm，非常依賴於函式物件處理容器的元素。因此，STL 預定義了許多函式物件、謂詞（predicate）、以及用於複合（composite）函式物件的 binder、member function adapter、 pointer to function adapters、 negaters、 function objects base structure。由於 STL 中的 algorithm 使用函式物件作為引數時，一般都是傳值呼叫，所以函式物件應該仔細設計其複製建構函式。

2.1 預定義的函式物件

C++98 在標頭檔案 functional 中定義了下述函式物件:

plus 	結果為 (param1 + param2)

minus 	結果為 (param1 - param2)

multiplies 	結果為 (param1 * param2)

divides 	結果為 (param1 /param2)

modulus 	結果為 (param1 % param2)

2.2 謂詞（predicate）

返回布林值（或者可以隱式轉換為布林值）的函式物件。用於 STL 中的 algorithm 時，謂詞應該是無狀態的（ stateless）函式物件，即謂詞的結果不依賴於內部的資料成員。這是因為 STL 中的 algorithm 不保證內部實現時對傳入的謂詞要複製多少次。

C++98 在標頭檔案 functional 中定義了下述謂詞:

equal_to 	結果為 (param1 == param2)
notequalto 	結果為 (param1 != param2)
less 	結果為 (param1 	結果為 (param1> param2)
less_equal 	結果為 (param1 	結果為 (param1>= param2)
logical_not 	結果為 (!param1)
logical_and 	結果為 (param1 && param2)
logical_or 	結果為 (param1

param2)

2.3 Function Adapter

用於組合（combine）、變換（transform）、操作（manipulate）函式物件、特定引數值、或者特定函式。進一步細分為：

2.3.1 Binder

C++98 在標頭檔案 functional 中定義了兩個函式 bind1st 與 bind2nd，返回值為 binder1st、binder2nd 型別。用於把二元函式物件分別繫結第一個、第二個引數後成為單元函式物件。

2.3.2 Negater

negate 把一個作為謂詞的函式物件取反。C++98 在標頭檔案 functional 中定義了兩個函式 not1 與 not2，返回值為 unarynegate、binarynegate 型別。

2.3.3 Member function adapter

Member function adapter 用於把類的成員函式用作 STL 中的 algorithm 的引數。C++98 在標頭檔案 functional 中定義了:

函式 memfun，返回值為 memfun_t 型別，用於透過一個類物件指標來呼叫成員函式指標。
函式 memfunref，返回值為 memfunref_t 型別，用於透過一個類物件引用來呼叫成員函式指標。

2.3.4 Pointer to function adapter

函式指標介面卡（Pointer to function adapter）是把函式指標包裝為一個函式物件，以便 STL 中的 algorithm 用函式物件作為統一的引數型別，不用再考慮以函式指標作為傳入引數的情形。C++98 在標頭檔案 functional 中定義了:

函式 ptrfun，返回值為 pointertounaryfunction 型別，包裝了一個單引數的函式指標。
過載函式 ptrfun，返回值為 pointertobinaryfunction 型別，包裝了一個雙引數的函式指標。

2.4 Function Object Base

函式物件基類（Function Object Base）定義在標頭檔案 functional 中，用作 STL 的預定義的與函式物件有關的各個類的基類，其中定義了幾個型別，分別表示函式呼叫的各個引數型別、結果型別。

unaryfunction 類，定義了 2 個型別：argumenttype、result_type；
binaryfunction 類，定義了 3 個型別：firstargumenttype、secondargumenttype、resulttype；

Python

Python 程式設計中，函式是作為頭等物件（first-class object），可以如同普通的字串、數值、list 等物件那樣操作。這使得大部分編寫函式物件都是不必須的。

任何物件定義了call 方法，就具有了可以當作函式呼叫的語法。例如下面的做累加的類

class Accumulator (object):

def init(self, n):

self.n = n

def call(self, x):

self.n += x

return self.n

一個使用例子：

>>> a = Accumulator (4)

>>> a (5)

9

>>> a (2)

11

>>> b = Accumulator (42)

>>> b (7)

49

因為函式就是物件，可當作區域性變數定義、確定其屬性（內部狀態）、作為別的函式的返回值。例如:

def Accumulator (n):

def inc (x):

inc.n += x

return inc.n

inc.n = n

return inc

Python 3 中，可以用函式閉包來建立函式物件：

def Accumulator (n):

def inc (x):

nonlocal n

n += x

return n

return inc

進一步閱讀

David Vandevoorde & Nicolai M Josuttis (2006). C++ Templates: The Complete Guide, ISBN 0-201-73484-2: Specifically, chapter 22 is devoted to function objects.