最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++11 中的std::function和std::bind詳解

 更新時(shí)間:2021年10月11日 10:33:11   作者:georgeguo  
這篇文章主要介紹了C++ 11 std::function和std::bind,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

1. 可調(diào)用對(duì)象

可調(diào)用對(duì)象有一下幾種定義:

  • 是一個(gè)函數(shù)指針,參考 C++ 函數(shù)指針和函數(shù)類(lèi)型;
  • 是一個(gè)具有operator()成員函數(shù)的類(lèi)的對(duì)象;
  • 可被轉(zhuǎn)換成函數(shù)指針的類(lèi)對(duì)象;
  • 一個(gè)類(lèi)成員函數(shù)指針;

C++中可調(diào)用對(duì)象的雖然都有一個(gè)比較統(tǒng)一的操作形式,但是定義方法五花八門(mén),這樣就導(dǎo)致使用統(tǒng)一的方式保存可調(diào)用對(duì)象或者傳遞可調(diào)用對(duì)象時(shí),會(huì)十分繁瑣。C++11中提供了std::function和std::bind統(tǒng)一了可調(diào)用對(duì)象的各種操作。

不同類(lèi)型可能具有相同的調(diào)用形式,如:

// 普通函數(shù)
int add(int a, int b){return a+b;} 
// lambda表達(dá)式
auto mod = [](int a, int b){ return a % b;}
// 函數(shù)對(duì)象類(lèi)
struct divide{
    int operator()(int denominator, int divisor){
        return denominator/divisor;
    }
};

上述三種可調(diào)用對(duì)象雖然類(lèi)型不同,但是共享了一種調(diào)用形式:

int(int ,int)

std::function就可以將上述類(lèi)型保存起來(lái),如下:

std::function<int(int ,int)>  a = add; 
std::function<int(int ,int)>  b = mod ; 
std::function<int(int ,int)>  c = divide(); 

2. std::function

  • std::function 是一個(gè)可調(diào)用對(duì)象包裝器,是一個(gè)類(lèi)模板,可以容納除了類(lèi)成員函數(shù)指針之外的所有可調(diào)用對(duì)象,它可以用統(tǒng)一的方式處理函數(shù)、函數(shù)對(duì)象、函數(shù)指針,并允許保存和延遲它們的執(zhí)行。
  • 定義格式:std::function<函數(shù)類(lèi)型>。
  • std::function可以取代函數(shù)指針的作用,因?yàn)樗梢匝舆t函數(shù)的執(zhí)行,特別適合作為回調(diào)函數(shù)使用。它比普通函數(shù)指針更加的靈活和便利。

3. std::bind

可將std::bind函數(shù)看作一個(gè)通用的函數(shù)適配器,它接受一個(gè)可調(diào)用對(duì)象,生成一個(gè)新的可調(diào)用對(duì)象來(lái)“適應(yīng)”原對(duì)象的參數(shù)列表。

std::bind將可調(diào)用對(duì)象與其參數(shù)一起進(jìn)行綁定,綁定后的結(jié)果可以使用std::function保存。std::bind主要有以下兩個(gè)作用:

  • 將可調(diào)用對(duì)象和其參數(shù)綁定成一個(gè)防函數(shù);
  • 只綁定部分參數(shù),減少可調(diào)用對(duì)象傳入的參數(shù)。

3.1 std::bind綁定普通函數(shù)

    double my_divide (double x, double y) {return x/y;}
    auto fn_half = std::bind (my_divide,_1,2);  
    std::cout << fn_half(10) << '\n';                        // 5
  • bind的第一個(gè)參數(shù)是函數(shù)名,普通函數(shù)做實(shí)參時(shí),會(huì)隱式轉(zhuǎn)換成函數(shù)指針。因此std::bind (my_divide,_1,2)等價(jià)于std::bind (&my_divide,_1,2);
  • _1表示占位符,位于<functional>中,std::placeholders::_1;

3.2 std::bind綁定一個(gè)成員函數(shù)

    struct Foo {
        void print_sum(int n1, int n2)
        {
            std::cout << n1+n2 << '\n';
        }
        int data = 10;
    };
    int main() 
    {
        Foo foo;
        auto f = std::bind(&Foo::print_sum, &foo, 95, std::placeholders::_1);
        f(5); // 100
    }
  • bind綁定類(lèi)成員函數(shù)時(shí),第一個(gè)參數(shù)表示對(duì)象的成員函數(shù)的指針,第二個(gè)參數(shù)表示對(duì)象的地址。
  • 必須顯示的指定&Foo::print_sum,因?yàn)榫幾g器不會(huì)將對(duì)象的成員函數(shù)隱式轉(zhuǎn)換成函數(shù)指針,所以必須在Foo::print_sum前添加&;
  • 使用對(duì)象成員函數(shù)的指針時(shí),必須要知道該指針屬于哪個(gè)對(duì)象,因此第二個(gè)參數(shù)為對(duì)象的地址 &foo;

3.3 綁定一個(gè)引用參數(shù)

默認(rèn)情況下,bind的那些不是占位符的參數(shù)被拷貝到bind返回的可調(diào)用對(duì)象中。但是,與lambda類(lèi)似,有時(shí)對(duì)有些綁定的參數(shù)希望以引用的方式傳遞,或是要綁定參數(shù)的類(lèi)型無(wú)法拷貝。

#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <sstream>
using namespace std::placeholders;
using namespace std;
ostream & print(ostream &os, const string& s, char c)
{
    os << s << c;
    return os;
}
int main()
{
    vector<string> words{"helo", "world", "this", "is", "C++11"};
    ostringstream os;
    char c = ' ';
    for_each(words.begin(), words.end(), 
                   [&os, c](const string & s){os << s << c;} );
    cout << os.str() << endl;
    ostringstream os1;
    // ostream不能拷貝,若希望傳遞給bind一個(gè)對(duì)象,
    // 而不拷貝它,就必須使用標(biāo)準(zhǔn)庫(kù)提供的ref函數(shù)
    for_each(words.begin(), words.end(),
                   bind(print, ref(os1), _1, c));
    cout << os1.str() << endl;
}

4. 指向成員函數(shù)的指針

通過(guò)下面的例子,熟悉一下指向成員函數(shù)的指針的定義方法。

    #include <iostream>
    struct Foo {
        int value;
        void f() { std::cout << "f(" << this->value << ")\n"; }
        void g() { std::cout << "g(" << this->value << ")\n"; }
    };
    void apply(Foo* foo1, Foo* foo2, void (Foo::*fun)()) {
        (foo1->*fun)();  // call fun on the object foo1
        (foo2->*fun)();  // call fun on the object foo2
    }
    int main() {
        Foo foo1{1};
        Foo foo2{2};
        apply(&foo1, &foo2, &Foo::f);
        apply(&foo1, &foo2, &Foo::g);
    }
  • 成員函數(shù)指針的定義:void (Foo::*fun)(),調(diào)用是傳遞的實(shí)參: &Foo::f;
  • fun為類(lèi)成員函數(shù)指針,所以調(diào)用是要通過(guò)解引用的方式獲取成員函數(shù)*fun,即(foo1->*fun)();

總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • C++ 反射機(jī)制詳解及實(shí)例代碼

    C++ 反射機(jī)制詳解及實(shí)例代碼

    這篇文章主要介紹了C++ 反射機(jī)制詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • C++ 中cerr和cout的區(qū)別實(shí)例詳解

    C++ 中cerr和cout的區(qū)別實(shí)例詳解

    這篇文章主要介紹了C++ 中cerr和cout的區(qū)別實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-09-09
  • C語(yǔ)言中socket相關(guān)網(wǎng)絡(luò)編程函數(shù)小結(jié)

    C語(yǔ)言中socket相關(guān)網(wǎng)絡(luò)編程函數(shù)小結(jié)

    這篇文章主要介紹了C語(yǔ)言中socket相關(guān)網(wǎng)絡(luò)編程函數(shù)小結(jié),是C語(yǔ)言入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • VS2019中QT連接及使用的方法步驟

    VS2019中QT連接及使用的方法步驟

    這篇文章主要介紹了VS2019中QT連接及使用的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • C語(yǔ)言指針應(yīng)用簡(jiǎn)單實(shí)例

    C語(yǔ)言指針應(yīng)用簡(jiǎn)單實(shí)例

    這篇文章主要介紹了C語(yǔ)言指針應(yīng)用簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C++自動(dòng)生成迷宮游戲

    C++自動(dòng)生成迷宮游戲

    這篇文章主要為大家詳細(xì)介紹了C++自動(dòng)生成迷宮游戲,運(yùn)用并查集自動(dòng)生成迷宮地圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • c++中關(guān)于int、long、long?long等取值范圍

    c++中關(guān)于int、long、long?long等取值范圍

    這篇文章主要介紹了c++中關(guān)于int、long、long?long等取值范圍,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • C++淺析引用的定義與使用

    C++淺析引用的定義與使用

    引用是C++一個(gè)很重要的特性,顧名思義是某一個(gè)變量或?qū)ο蟮膭e名,對(duì)引用的操作與對(duì)其所綁定的變量或?qū)ο蟮牟僮魍耆葍r(jià),這篇文章主要給大家總結(jié)介紹了C++中引用的相關(guān)知識(shí)點(diǎn),需要的朋友可以參考下
    2022-07-07
  • OpenCV實(shí)現(xiàn)區(qū)域分割和區(qū)域生長(zhǎng)

    OpenCV實(shí)現(xiàn)區(qū)域分割和區(qū)域生長(zhǎng)

    區(qū)域分割是圖像處理中一個(gè)重要的任務(wù),本文主要介紹了OpenCV實(shí)現(xiàn)區(qū)域分割和區(qū)域生長(zhǎng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • C/C++實(shí)現(xiàn)線性單鏈表的示例代碼

    C/C++實(shí)現(xiàn)線性單鏈表的示例代碼

    使用鏈存儲(chǔ)結(jié)構(gòu)的線性存儲(chǔ)結(jié)構(gòu)為線性單鏈表,本文將分別利用C語(yǔ)言和C++實(shí)現(xiàn)線性單鏈表,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-05-05

最新評(píng)論

惠来县| 敖汉旗| 焉耆| 赫章县| 土默特左旗| 翁牛特旗| 山东省| 万山特区| 芒康县| 车致| 吉木乃县| 民和| 泊头市| 积石山| 托克逊县| 会东县| 遂川县| 乌海市| 台南市| 宜州市| 淮南市| 嘉兴市| 和田市| 桐柏县| 鹿泉市| 布拖县| 章丘市| 兴海县| 江津市| 和顺县| 邛崃市| 武强县| 荆门市| 轮台县| 饶河县| 巴南区| 翼城县| 青州市| 丘北县| 元氏县| 南京市|