青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Benjamin

靜以修身,儉以養(yǎng)德,非澹薄無(wú)以明志,非寧?kù)o無(wú)以致遠(yuǎn)。
隨筆 - 398, 文章 - 0, 評(píng)論 - 196, 引用 - 0
數(shù)據(jù)加載中……

c++和closure(閉包)

一、定義: 是帶有上下文的函數(shù)。說(shuō)白了,就是有狀態(tài)的函數(shù)。必須有上下文才能使用。
函數(shù), 帶上了狀態(tài), 就變成了閉包了. 什么叫 "帶上狀態(tài)" 呢? 意思是這個(gè)閉包有屬于自己的變量, 這些個(gè)變量的值是創(chuàng)建閉包的時(shí)候設(shè)置的, 并在調(diào)用閉包的時(shí)候, 可以訪問(wèn)這些變量.
函數(shù)是代碼, 狀態(tài)是一組變量 ,將代碼和一組變量捆綁 (bind) , 就形成了閉包 ,內(nèi)部包含 static 變量的函數(shù), 不是閉包, 因?yàn)檫@個(gè) static 變量不能捆綁. 你不能捆綁不同的 static 變量. 這個(gè)在編譯的時(shí)候已經(jīng)確定了.
二、c++實(shí)現(xiàn)閉包的方法:
1、重載 operator() 例子
class MyFunctor { public: MyFunctor(float f) : round(f) {} int operator()(float f) { return f + round; } private: float round; }; float round = 0.5; MyFunctor f(round);

2、std::bind
int my_func(float f, float round) { return f + round; } float round = 0.5; std::function<int(float,float)> f = my_func;

3、lambda表達(dá)式,語(yǔ)法形式如下: [函數(shù)對(duì)象參數(shù)] (操作符重載函數(shù)參數(shù)) mutable或exception聲明 -> 返回值類型 { …函數(shù)體…}
[函數(shù)對(duì)象參數(shù)],例如[&,a,b]標(biāo)識(shí)一個(gè)Lambda的開(kāi)始,這部分必須存在,不能省略。函數(shù)對(duì)象參數(shù)是傳遞給編譯器自動(dòng)生成的函數(shù)對(duì)象類的構(gòu)造函數(shù)的。

函數(shù)對(duì)象參數(shù)有以下形式:
[ ] 空沒(méi)有使用任何函數(shù)對(duì)象參數(shù)。
[=] 函數(shù)體內(nèi)可以使用Lambda所在作用范圍內(nèi)所有可見(jiàn)的局部變量(包括Lambda所在類的this),并且是值傳遞方式(相當(dāng)于編譯器自動(dòng)為我們按值傳遞了所有局部變量)。
[&] 函數(shù)體內(nèi)可以使用Lambda所在作用范圍內(nèi)所有可見(jiàn)的局部變量(包括Lambda所在類的this),并且是引用傳遞方式(相當(dāng)于編譯器自動(dòng)為我們按引用傳遞了所有局部變量)。
[this] 函數(shù)體內(nèi)可以使用Lambda所在類中的成員變量。
[a] 將a按值進(jìn)行傳遞。按值進(jìn)行傳遞時(shí),函數(shù)體內(nèi)不能修改傳遞進(jìn)來(lái)的a的拷貝,因?yàn)槟J(rèn)情況下函數(shù)是const的。要修改傳遞進(jìn)來(lái)的a的拷貝,可以添加mutable修飾符。
[&a] 將a按引用進(jìn)行傳遞。
[a, &b] 將a按值進(jìn)行傳遞,b按引用進(jìn)行傳遞。
[=,&a, &b] 除a和b按引用進(jìn)行傳遞外,其他參數(shù)都按值進(jìn)行傳遞。
[&, a, b] 除a和b按值進(jìn)行傳遞外,其他參數(shù)都按引用進(jìn)行傳遞。

(操作符重載函數(shù)參數(shù)),例如(int a,int &b)標(biāo)識(shí)重載的()操作符的參數(shù),沒(méi)有參數(shù)時(shí),這部分可以省略。參數(shù)可以通過(guò)按值(如:(a,b))和按引用(如:(&a,&b))兩種方式進(jìn)行傳遞
mutable與exception聲明,例如 mutable throw(),可省略
按值傳遞函數(shù)對(duì)象參數(shù)時(shí),加上mutable修飾符后,可以修改按值傳遞進(jìn)來(lái)的拷貝(注意是能修改拷貝,而不是值本身,如果沒(méi)有添加mutable,相當(dāng)于對(duì)函數(shù)參數(shù)的增加了const修飾,無(wú)法修改參數(shù))。exception聲明用于指定函數(shù)拋出的異常,如拋出整數(shù)類型的異常,可以使用throw(int)。

示例:
->返回值類型,例如 ->int 表示返回 int類型
標(biāo)識(shí)函數(shù)返回值的類型,當(dāng)返回值為void,或者函數(shù)體中只有一處return的地方(此時(shí)編譯器可以自動(dòng)推斷出返回值類型)時(shí),這部分可以省略。
{函數(shù)體},例如{cout<<“abc”;},不可省略,可以為空

// 無(wú)函數(shù)對(duì)象參數(shù),輸出:1 2   {    for_each(vctTemp.begin(), vctTemp.end(), [](int v){ cout << v << endl; });   }
   
// 以值方式傳遞作用域內(nèi)所有可見(jiàn)的局部變量(包括this),輸出:11 12   {    int a = 10;    for_each(vctTemp.begin(), vctTemp.end(), [=](int v){ cout << v+a << endl; });   }   
 // 以引用方式傳遞作用域內(nèi)所有可見(jiàn)的局部變量(包括this),輸出:11 13 12   {    int a = 10;    for_each(vctTemp.begin(), vctTemp.end(), [&](int v)mutable{ cout << v+a << endl; a++; });    cout << a << endl;   }   
 // 以值方式傳遞局部變量a,輸出:11 13 10   {    int a = 10;    for_each(vctTemp.begin(), vctTemp.end(), [a](int v)mutable{ cout << v+a << endl; a++; });    cout << a << endl;   }
   
// 以引用方式傳遞局部變量a,輸出:11 13 12   {    int a = 10;    for_each(vctTemp.begin(), vctTemp.end(), [&a](int v){ cout << v+a << endl; a++; });    cout << a << endl;   }   
 // 傳遞this,輸出:21 22   {    for_each(vctTemp.begin(), vctTemp.end(), [this](int v){ cout << v+m_nData << endl; });   }    
// 除b按引用傳遞外,其他均按值傳遞,輸出:11 12 17   {    int a = 10;    int b = 15;    for_each(vctTemp.begin(), vctTemp.end(), [=, &b](int v){ cout << v+a << endl; b++; });    cout << b << endl;   }

int temp = 10;
vector<int> ivec = {30, -10, -20, 50, 40 ,100, -50};
std::sort(ivec.begin(), ivec.end(), [](const int &x, const int &y) {return abs(x) < abs(y);});
std::for_each(ivec.begin(), ivec.end(), [&](int &x) { x += temp; cout << x << endl;});
三、注意事項(xiàng):
比較上面三種方式,有一些細(xì)節(jié)需要注意:

1. closure的狀態(tài)特指其運(yùn)行的上下文。 closure將存貯它運(yùn)行時(shí)需要的上下文,從而保證在closure創(chuàng)建時(shí)的上下文可以在closure運(yùn)行時(shí)依然有效。

比如round就是closure的上下文。保存上下文的這一特點(diǎn)通常被稱作“capture”或者是"bind"。 capture可以自己寫(xiě),比如MyFuctor f(round); 也可以用boost::bind。

當(dāng)然最方便的還是讓編譯器幫你自動(dòng)完成。編譯器將自動(dòng)識(shí)別closure用到的變量,然后創(chuàng)建一個(gè)匿名的類,將這個(gè)變量保存到匿名類的成員變量中。

C++中有兩種capture方式,by value和by reference。寫(xiě)法是[=]和[&]。

需要注意的是,capture by reference是不會(huì)修改被capture變量的生命周期的,你要保證被capture的變量在closure運(yùn)行時(shí)是有效的。

這一點(diǎn)不像Java,Java中變量被capture的話,就變成被引用了,從而GC不會(huì)回收它。

2. closure的類型是隱藏的,每次創(chuàng)建一個(gè)closure,編譯器都會(huì)創(chuàng)建一個(gè)新的類型。

如果你想保存一個(gè)clousre時(shí)就不是那么直接,因?yàn)槟悴恢浪念愋汀_@時(shí)那需要一些模板技巧,可參考boost::function的實(shí)現(xiàn)。

簡(jiǎn)單的方式是直接用std::function來(lái)保存。

std::function<int(float)> closure;

closure = [](float f) { return 0.0f };

closure = [](float f) { return 1.0f };

四、閉包(匿名函數(shù))用處,可以是流程更清晰,易于理解,一般不能單獨(dú)使用,必須有上下文,閉包里處理的是上下文中的一些變量。一般情況下不能單獨(dú)使用
auto Do=[&]()
{

}
auto nextDo=[=](){
}

posted on 2018-05-27 18:17 Benjamin 閱讀(836) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C/C++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品免费观看在线| 久久国产精品亚洲77777| 久久久久久夜| 欧美在线免费播放| 国产一区二区精品久久91| 欧美影院成年免费版| 久久爱91午夜羞羞| 亚洲狠狠婷婷| 一本色道久久88亚洲综合88| 国产裸体写真av一区二区| 久久婷婷国产综合国色天香| 国产在线不卡| 老牛嫩草一区二区三区日本| 欧美成人dvd在线视频| 一区二区欧美在线观看| 亚洲欧美一区在线| 亚洲国产婷婷综合在线精品| 一区二区日韩免费看| 国产一区二区久久久| 亚洲黄色成人| 久久免费视频一区| 欧美不卡高清| 欧美日韩精选| 狂野欧美激情性xxxx欧美| 欧美韩日高清| 久久精品免费| 欧美日本一区| 久久综合九色欧美综合狠狠| 欧美日本亚洲| 美女图片一区二区| 欧美一区二区精品在线| 亚洲欧洲日韩在线| 亚洲综合不卡| 99国内精品久久| 久久www成人_看片免费不卡| 亚洲一区二区三区四区中文| 女人色偷偷aa久久天堂| 欧美一区二区免费视频| 欧美精品首页| 免费成人av在线看| 国产精品亚洲一区| 亚洲精品影院| 亚洲国产精品一区二区三区| 午夜日韩福利| 午夜视频久久久| 欧美日韩在线视频首页| 欧美激情综合色| 国产一区二区三区高清在线观看 | 国内精品伊人久久久久av影院 | 久久本道综合色狠狠五月| 欧美国产精品久久| 欧美二区在线播放| 激情文学综合丁香| 欧美在线电影| 久久久久久网站| 国产欧美91| 亚洲一区在线视频| 亚洲在线免费| 国产精品高潮在线| 在线视频一区二区| 亚洲综合社区| 国产精品久久久久久久7电影| 亚洲人成在线播放网站岛国| 亚洲国产一区二区a毛片| 久久婷婷丁香| 亚洲福利视频一区| 日韩视频中午一区| 欧美精品色一区二区三区| 亚洲欧洲日产国产综合网| 99精品免费| 欧美日韩一区二区三区在线看| 日韩视频欧美视频| 亚洲在线观看免费| 国产美女精品| 久久精品国产一区二区电影 | 亚洲国产三级网| 亚洲日本激情| 欧美日韩在线第一页| 亚洲午夜一区二区三区| 国产精品豆花视频| 一区二区欧美日韩| 中文久久精品| 国产美女精品人人做人人爽| 欧美一区二区视频在线观看2020 | 亚洲综合色丁香婷婷六月图片| 国产精品五区| 久久欧美肥婆一二区| 91久久线看在观草草青青| 亚洲男女毛片无遮挡| 国模精品娜娜一二三区| 免费成年人欧美视频| 一区二区久久| 久久久久网站| 一本色道久久综合亚洲精品不| 国产精品久久91| 久久人人97超碰精品888| 亚洲人成网站999久久久综合| 亚洲欧美清纯在线制服| 激情综合在线| 欧美亚一区二区| 每日更新成人在线视频| 亚洲精品欧美极品| 国产亚洲欧美日韩一区二区| 欧美成人资源网| 午夜精品免费在线| 亚洲精品国产精品久久清纯直播 | 亚洲综合第一| 1024成人| 国产精品日韩在线一区| 欧美激情黄色片| 久久成人精品无人区| 一本色道久久精品| 欧美激情成人在线| 欧美在线三级| 亚洲一区二区欧美| 亚洲日本欧美日韩高观看| 国模私拍视频一区| 国产精品久久久久久亚洲调教| 蜜臀久久久99精品久久久久久| 亚洲综合精品四区| 一区二区久久久久久| 亚洲高清资源| 蜜桃av久久久亚洲精品| 久久精品国产一区二区三| 亚洲伊人伊色伊影伊综合网| 亚洲人午夜精品| 亚洲国产精品福利| 黄色欧美日韩| 国模私拍一区二区三区| 国产欧美日韩免费看aⅴ视频| 欧美四级在线观看| 欧美日本中文字幕| 欧美理论电影网| 欧美激情综合| 欧美极品在线视频| 欧美大胆人体视频| 欧美激情精品久久久久| 欧美成人精品在线观看| 欧美h视频在线| 免费在线亚洲| 欧美激情一区二区三区成人| 欧美韩日亚洲| 欧美日韩国产区一| 欧美午夜国产| 国产精品你懂的在线| 国产精品亚洲综合色区韩国| 国产精品美女999| 国产精品色婷婷| 国产欧美亚洲一区| 国产综合第一页| 亚洲福利视频在线| 狠狠入ady亚洲精品经典电影| 久久综合狠狠综合久久激情| 巨乳诱惑日韩免费av| 欧美韩国一区| 国产精品激情偷乱一区二区∴| 欧美午夜视频网站| 国产香蕉久久精品综合网| 国产一区白浆| 亚洲激情成人| 亚洲小视频在线| 久久国产精品72免费观看| 久久午夜视频| 亚洲黄色小视频| 一区二区三区精品久久久| 亚洲欧美一级二级三级| 久久久久久免费| 欧美精品一区二区视频| 国产精品视频精品| 一区在线免费| 亚洲视频电影图片偷拍一区| 欧美一区国产在线| 欧美成年网站| 亚洲四色影视在线观看| 久久亚洲高清| 欧美午夜不卡在线观看免费| 国内精品久久久久久影视8| 99精品热视频只有精品10| 欧美伊人久久久久久午夜久久久久 | 亚洲国产精品www| 亚洲在线1234| 欧美黄色免费| 亚洲欧美韩国| 欧美黄色日本| 国语自产精品视频在线看8查询8 | 好吊色欧美一区二区三区视频| aa成人免费视频| 麻豆精品传媒视频| 亚洲在线观看免费| 欧美激情亚洲综合一区| 国内欧美视频一区二区| 中文在线资源观看网站视频免费不卡 | 欧美视频免费在线| 亚洲成人在线视频网站| 亚洲欧美在线x视频| 亚洲精品三级| 男人的天堂成人在线| 国语自产偷拍精品视频偷| 亚洲欧洲av一区二区| 亚洲精品视频在线|