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

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麻豆精品国产自产在线观看| 亚洲愉拍自拍另类高清精品| 亚洲精品之草原avav久久| 最新国产の精品合集bt伙计| 亚洲日韩欧美视频| 亚洲午夜国产一区99re久久 | 亚洲高清免费| 欧美成人午夜影院| 99视频超级精品| 欧美一区二区| 欧美欧美全黄| 国产欧美一级| 亚洲欧洲精品一区二区| 亚洲制服av| 免费观看一级特黄欧美大片| 亚洲精品免费网站| 午夜精品一区二区三区四区| 欧美阿v一级看视频| 国产精品日韩在线观看| 亚洲国产高潮在线观看| 亚洲一区三区在线观看| 欧美va亚洲va香蕉在线| 一本色道久久综合| 免费日韩一区二区| 国内视频精品| 午夜精品久久久久久久99水蜜桃| 葵司免费一区二区三区四区五区| 亚洲作爱视频| 欧美大片免费久久精品三p| 国产精品视区| 中日韩美女免费视频网址在线观看| 欧美日韩中字| 精品69视频一区二区三区| 亚洲影院一区| 亚洲激情小视频| 欧美专区在线观看| 狠狠色丁香婷婷综合| 亚洲美女电影在线| 亚洲全黄一级网站| 欧美日韩国产片| 一区二区三区久久精品| 亚洲日本黄色| 国产精品久久91| 亚洲欧美影音先锋| 久久久久久久久久久久久女国产乱| 国产免费亚洲高清| 久久久久久婷| 欧美国产日韩xxxxx| 夜久久久久久| 亚洲欧美自拍偷拍| 亚洲国产第一| 亚洲视频国产视频| 亚洲国产欧美精品| 亚洲在线观看免费| 狠狠v欧美v日韩v亚洲ⅴ| 久久综合九色综合欧美狠狠| 欧美美女视频| 亚洲午夜黄色| 欧美高清视频一二三区| 久久se精品一区精品二区| 亚洲一区二区在| 国产精品久久国产愉拍| 亚洲无亚洲人成网站77777| 一区二区三区国产| 一色屋精品视频免费看| 亚洲激情成人网| 狠狠爱综合网| 久久激情综合| 久久爱另类一区二区小说| 欧美日本成人| 日韩视频一区二区| 亚洲尤物视频在线| 国产精品久久77777| 午夜一区不卡| 久久久久久综合| 亚洲人成在线观看| 欧美精品一区二区三区蜜臀| 91久久久一线二线三线品牌| 亚洲免费高清视频| 国产精品欧美日韩一区| 欧美主播一区二区三区| 欧美高清在线精品一区| 99在线精品视频| 国产亚洲精品美女| 欧美精品日韩一区| 国产在线视频欧美一区二区三区| 久久久久久久久久久久久久一区| 另类图片综合电影| 中文一区二区| 亚洲第一主播视频| 国产区日韩欧美| 欧美黑人国产人伦爽爽爽| 一本色道精品久久一区二区三区| 久久国产视频网站| 久久大逼视频| 日韩午夜电影| 亚洲美女色禁图| 亚洲国产三级网| 久久亚洲欧美| 久久久欧美一区二区| 久久成人国产| 欧美一区三区三区高中清蜜桃| 一本色道久久88精品综合| 午夜激情久久久| 在线一区免费观看| 99精品久久久| 一区二区三区久久| 亚洲视频免费在线| 亚洲私人黄色宅男| 亚洲午夜av在线| 亚洲一区二区视频在线| 亚洲视频在线观看网站| 亚洲性线免费观看视频成熟| 亚洲伦理自拍| 先锋影音国产精品| 麻豆精品在线观看| 欧美日韩精品一区二区天天拍小说| 欧美精品亚洲一区二区在线播放| 欧美刺激午夜性久久久久久久| 欧美精品亚洲一区二区在线播放| 国产精品欧美一区二区三区奶水 | 久久精品国产69国产精品亚洲| 亚洲一区二区三区免费在线观看 | 一区二区三区 在线观看视频| 亚洲精品国产精品国自产在线 | 欧美国产精品人人做人人爱| 国产精品久久久久久久久久ktv| 性色av一区二区三区| 久久久久国产精品午夜一区| 日韩亚洲在线| 欧美成人精品在线视频| 久久精品日韩| 亚洲黄色在线看| 亚洲精品国精品久久99热| 美女精品在线观看| 中文一区二区在线观看| 欧美岛国激情| 一本色道久久综合亚洲精品婷婷 | 久久夜色精品亚洲噜噜国产mv | 久久激情五月丁香伊人| 欧美精品久久久久久久久久| 国产一区二区三区四区在线观看| 亚洲小视频在线观看| 欧美成人免费va影院高清| 午夜亚洲福利| 欧美日韩亚洲视频| 亚洲国产婷婷香蕉久久久久久99 | 午夜精品一区二区三区在线视| 亚洲精品一区二区三区福利| 亚洲国产人成综合网站| 欧美激情第9页| 欧美亚洲午夜视频在线观看| 欧美亚洲免费在线| 日韩视频三区| 日韩一区二区精品| 欧美香蕉大胸在线视频观看| 一区二区日韩| 亚洲国产日韩一区二区| 蜜臀91精品一区二区三区| 在线观看三级视频欧美| 亚洲大片一区二区三区| 欧美日韩国产成人在线| 亚洲欧美三级在线| 久久久久国内| 亚洲视频在线二区| 久久国产精品72免费观看| 亚洲欧洲视频| 欧美一级久久久| 亚洲深爱激情| 欧美大片网址| 欧美国产日韩二区| 在线精品视频在线观看高清| 免费在线观看精品| 在线综合亚洲| 欧美日韩1区2区3区| 亚洲激情综合| 夜色激情一区二区| 欧美另类变人与禽xxxxx| 久久一区二区三区四区| 亚洲一区二区三区在线观看视频| 亚洲另类自拍| 欧美日韩高清免费| 亚洲精品之草原avav久久| 亚洲高清自拍| 欧美日韩亚洲免费| 欧美一区午夜精品| 亚洲韩国青草视频| 午夜在线精品偷拍| 夜夜爽99久久国产综合精品女不卡 | 久久高清国产| 狠狠88综合久久久久综合网| 亚洲在线免费| 日韩午夜在线观看视频| 亚洲国产成人高清精品| 中文欧美在线视频| 中文一区字幕| 欧美成人一品| 久久综合九色99|