iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 11
0
Software Development

山姆大叔談 C++:從歷史談起,再給個定義—Modern C++ 解惑系列 第 11

DAY 10:Function Object and std::function,卷一

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:

  1. Function
  2. Function Pointer
  3. Class or Struct with operator()
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 使用便利性提昇百分之一千的超級好功能。

延伸閱讀

Yes


上一篇
DAY 9:Modern C++ 要角,再談 auto
下一篇
DAY 11:Lambda,卷一:讓 STL 更親民的 Lambda 簡介
系列文
山姆大叔談 C++:從歷史談起,再給個定義—Modern C++ 解惑26
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
微中子
iT邦新手 4 級 ‧ 2019-09-23 07:59:50

話說 電子報怎麼後來就沒ㄌ

竟然追到這裡來了/images/emoticon/emoticon02.gif

其實已經編到一定程度,但一直發不出去。總覺是差了那麼一點,最新一刊主題是 GUI,九月底應該,我說「應該」發得出去。

0
ekids1234
iT邦新手 5 級 ‧ 2023-04-20 21:16:07
private:
    action_;

請問為何 action_ 不須要指定 type ?

因為那是 Bug,感謝/images/emoticon/emoticon38.gif

我要留言

立即登入留言