函数对象

**函式物件**（function object）是一個程式設計的物件允許被當作普通函式來呼叫。

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

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

## C++ 函式物件的實例

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

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

除了類類型函式物件，還有其他類型的函式物件，如使用成員函式指標或模板。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 使用函式物件作為參數時，一般都是傳值呼叫，所以函式物件應該仔細設計其_複製建構函式_。

### 預定義的函式物件

C++98 在標頭檔 functional 中定義了下述函式物件:
plus<type>() 結果為 (param1 + param2)
minus<type>() 結果為 (param1 - param2)
multiplies<type>() 結果為 (param1 \* param2)
divides<type>() 結果為 (param1 /param2)
modulus<type>() 結果為 (param1 % param2)

### 謂詞（predicate）

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

* equal\_to<type>() 結果為 (param1 == param2)
* not\_equal\_to<type>() 結果為 (param1 != param2)
* less<type>() 結果為 (param1 < param2)
* greater<type>() 結果為 (param1> param2)
* less\_equal<type>() 結果為 (param1 <= param2)
* greater\_equal<type>() 結果為 (param1>= param2)
* logical\_not<type>() 結果為 (!param1)
* logical\_and<type>() 結果為 (param1 && param2)
* logical\_or<type>() 結果為 (param1 || param2)

### Function Adapter

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

#### Binder

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

#### Negater

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

#### Member function adapter

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

* 函式 mem\_fun，返回值為 mem\_fun\_t 類型，用於通過一個類物件指標來呼叫成員函式指標。
* 函式 mem\_fun\_ref，返回值為 mem\_fun\_ref\_t 類型，用於通過一個類物件參照來呼叫成員函式指標。

#### Pointer to function adapter

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

* 函式 ptr\_fun，返回值為 pointer\_to\_unary\_function 類型，包裝了一個單參數的函式指標。
* 多載函式 ptr\_fun，返回值為 pointer\_to\_binary\_function 類型，包裝了一個雙參數的函式指標。

### Function Object Base

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

* unary\_function 類，定義了 2 個類型：argument\_type、result\_type；
* binary\_function 類，定義了 3 個類型：first\_argument\_type、second\_argument\_type、result\_type；

## Python

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

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

一個使用例子：

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

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

## 注釋

## 參考文獻

## 進一步閱讀

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

## 外部連結

* Function Objects (STL) by Gabriel&Andreas Fleseriu&Masur on February 22nd, 2006 （頁面存檔備份，存於網際網路檔案館）
* Description from the Portland Pattern Repository（頁面存檔備份，存於網際網路檔案館）
* C++ Advanced Design Issues - Asynchronous C++ （頁面存檔備份，存於網際網路檔案館） by Kevlin Henney
* The Function Pointer Tutorials （頁面存檔備份，存於網際網路檔案館） by Lars Haendel (2000/2001)
* Article "Generalized Function Pointers" by Herb Sutter
* Generic Algorithms for Java （頁面存檔備份，存於網際網路檔案館）
* PHP Functors - Function Objects in PHP
* What the heck is a functionoid, and why would I use one? (C++ FAQ)