C++bind

C++11中提供了std::bind。bind()函數的意義就像它的函數名一樣,是用來綁定函數調用的某些參數的。

bind的思想實際上是一種延遲計算的思想,將可調用對象保存起來,然後在需要的時候再調用。而且這種綁定是非常靈活的,不論是普通函數、函數對象、還是成員函數都可以綁定,而且其參數可以支持佔位符,比如你可以這樣綁定一個二元函數auto f = bind(&func, _1, _2);,調用的時候通過f(1,2)實現調用。

簡單的認爲就是std::bind就是std::bind1ststd::bind2nd的加強版。

怎麼使用std::bind

一個知識點厲不厲害,歸根到底還是要經過實踐的考驗,下面就來看看std::bind到底怎麼用。

先看看《C++11中的std::function》中那段代碼,std::function可以綁定全局函數,靜態函數,但是綁定類的成員函數時,必須要藉助std::bind的幫忙。但是話又說回來,不借助std::bind也是可以完成的,只需要傳一個*this變量進去就好了,比如:

#include <iostream>
#include <functional>
using namespace std;

class View
{
public:
    void onClick(int x, int y)
    {
        cout << "X : " << x << ", Y : " << y << endl;
    }
};

// 定義function類型, 三個參數
function<void(View, int, int)> clickCallback;

int main(int argc, const char * argv[])
{
    View button;

    // 指向成員函數
    clickCallback = &View::onClick;

    // 進行調用
    clickCallback(button, 10, 123);
    return 0;
}

再來一段示例談談怎麼使用std::bind代碼:

#include <iostream>
#include <functional>
using namespace std;

int TestFunc(int a, char c, float f)
{
    cout << a << endl;
    cout << c << endl;
    cout << f << endl;

    return a;
}

int main()
{
    auto bindFunc1 = bind(TestFunc, std::placeholders::_1, 'A', 100.1);
    bindFunc1(10);

    cout << "=================================\n";

    auto bindFunc2 = bind(TestFunc, std::placeholders::_2, std::placeholders::_1, 100.1);
    bindFunc2('B', 10);

    cout << "=================================\n";

    auto bindFunc3 = bind(TestFunc, std::placeholders::_2, std::placeholders::_3, std::placeholders::_1);
    bindFunc3(100.1, 30, 'C');

    return 0;
}

上面這段代碼主要說的是bind中std::placeholders的使用。 std::placeholders是一個佔位符。當使用bind生成一個新的可調用對象時,std::placeholders表示新的可調用對象的第 幾個參數和原函數的第幾個參數進行匹配,這麼說有點繞。比如:

auto bindFunc3 = bind(TestFunc, std::placeholders::_2, std::placeholders::_3, std::placeholders::_1);

bindFunc3(100.1, 30, 'C');

可以看到,在bind的時候,第一個位置是TestFunc,除了這個,參數的第一個位置爲佔位符std::placeholders::_2,這就表示,調用bindFunc3的時候,它的第二個參數和TestFunc的第一個參數匹配,以此類推。

以下是使用std::bind的一些需要注意的地方:

  • bind預先綁定的參數需要傳具體的變量或值進去,對於預先綁定的參數,是pass-by-value的;
  • 對於不事先綁定的參數,需要傳std::placeholders進去,從_1開始,依次遞增。placeholder是pass-by-reference的;
  • bind的返回值是可調用實體,可以直接賦給std::function對象;
  • 對於綁定的指針、引用類型的參數,使用者需要保證在可調用實體調用之前,這些參數是可用的;
  • 類的this可以通過對象或者指針來綁定。

爲什麼要用std::bind

當我們厭倦了使用std::bind1ststd::bind2nd的時候,現在有了std::bind,你完全可以放棄使用std::bind1ststd::bind2nd了。std::bind綁定的參數的個數不受限制,綁定的具體哪些參數也不受限制,由用戶指定,這個bind纔是真正意義上的綁定。

在Cocos2d-x中,我們可以看到,使用std::bind生成一個可調用對象,這個對象可以直接賦值給std::function對象;在類中有一個std::function的變量,這個std::functionstd::bind來賦值,而std::bind綁定的可調用對象可以是Lambda表達式或者類成員函數等可調用對象,這個是Cocos2d-x中的一般用法。

轉載地址;http://blog.csdn.net/zhoujianhua0591/article/details/49304141

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章