C++ 有一個概念叫 Function Object
(函數物件),寬鬆一點的定義是:任何可以被當做函數呼叫的「東西」都是一種 Function Object
,或叫 Functor
(沒辦法,C++ 人普遍愛縮寫)。
《The C++ Standard Libary》對於 Function Object 的定義如下:
You could say that anything that behaves like a function is a function. So, if you define an object that behaves as a function, it can be used like a function.
C++11 之前的時代有三種 Function Object:
void ThisIsFunctionObject(); // 1. Function
typedef void (*pfnAlsoFunctionObject)(); // 2. Function Pointer
struct IAmFunctionObjectToo // 3. Struct with operator()
{
void operator()(void) {}
};
C++11 引入了 std::function
(定義在 <functional> 標頭檔裡),從此函數在 C++ 語言成為「一等公民」,可以被當做變數傳來傳去,搭配之後會介紹的 Lambda
,讓整個 STL 威力備增,便利性也獲得大幅度提昇。
有了 std::function
,撰寫程式碼時可以很清楚表達意圖,例如:
class WhenLeaveDo final {
public:
explicit WhenLeaveDo(std::function<void()> action) :
action_(action)
{}
~WhenLeaveDo() { action_(); }
private:
std::function<void()> action_;
};
bool AllocateMemoryInside()
{
auto mem = malloc(sizeof(int));
if (mem == nullptr)
return false;
WhenLeaveDo clean_up([mem]() { free(mem);});
if (SomethingWentWrong())
return false;
return true;
}
WhenLeaveDo
的建構式(Ctor)明白指出接受一個沒有參數,沒有回傳值的 std::function
,任何符合條件的 Function Object 都能夠傳入,且會被存成類別成員(class member variable),並在解構式(Dtor)呼叫之。
實際應用搭配 Lambda
,在索取記憶體成功後,確保該記憶體在函數離開時釋出。(此例僅用做說明,上述程式碼可用 std::uniqur_ptr
取代)
宣告帶參數以及回傳值的 std::function
寫法如下:
std::function<bool()> PerformAction(std::function<bool(std::function<void()>)> callback)
{
return [=]() { callback(); };
}
上述程式碼片段主要示範 std::function
如何被當做參數以及回傳值使用。
auto
, std::function
, template 以及之後會介紹的 Lambda
讓 C++ 俱備了 Functional Programming 的潛力。
下一篇要談的是 Lambda
,這個讓 STL 使用便利性提昇百分之一千的超級好功能。
話說 電子報怎麼後來就沒ㄌ
竟然追到這裡來了
其實已經編到一定程度,但一直發不出去。總覺是差了那麼一點,最新一刊主題是 GUI,九月底應該,我說「應該」發得出去。
private:
action_;
請問為何 action_
不須要指定 type ?
因為那是 Bug,感謝