小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

C++11中的匿名函數(shù)(lambda函數(shù),lambda表達(dá)式)

 quasiceo 2013-05-09

C++11中的匿名函數(shù)(lambda函數(shù),lambda表達(dá)式)

  這篇文章是根據(jù)維基百科整理來的,原文請(qǐng)看:http://en./wiki/Anonymous_function#C.2B.2B

  C++11提供了對(duì)匿名函數(shù)的支持,稱為Lambda函數(shù)(也叫Lambda表達(dá)式). Lambda表達(dá)式具體形式如下:

    [capture](parameters)->return-type{body}

  如果沒有參數(shù),空的圓括號(hào)()可以省略.返回值也可以省略,如果函數(shù)體只由一條return語句組成或返回類型為void的話.形如:

     [capture](parameters){body}

  下面舉了幾個(gè)Lambda函數(shù)的例子:      

[](int x, int y) { return x + y; } // 隱式返回類型
[](int& x) { ++x; }   // 沒有return語句 -> lambda 函數(shù)的返回類型是'void'
[]() { ++global_x; }  // 沒有參數(shù),僅訪問某個(gè)全局變量
[]{ ++global_x; }     // 與上一個(gè)相同,省略了()

  可以像下面這樣顯示指定返回類型:  

[](int x, int y) -> int { int z = x + y; return z; }

  在這個(gè)例子中創(chuàng)建了一個(gè)臨時(shí)變量z來存儲(chǔ)中間值. 和普通函數(shù)一樣,這個(gè)中間值不會(huì)保存到下次調(diào)用. 什么也不返回的Lambda函數(shù)可以省略返回類型, 而不需要使用 -> void 形式.
  Lambda函數(shù)可以引用在它之外聲明的變量. 這些變量的集合叫做一個(gè)閉包. 閉包被定義在Lambda表達(dá)式聲明中的方括號(hào)[]內(nèi). 這個(gè)機(jī)制允許這些變量被按值或按引用捕獲.下面這些例子就是:  

[]        //未定義變量.試圖在Lambda內(nèi)使用任何外部變量都是錯(cuò)誤的.
[x, &y]   //x 按值捕獲, y 按引用捕獲.
[&]       //用到的任何外部變量都隱式按引用捕獲
[=]       //用到的任何外部變量都隱式按值捕獲
[&, x]    //x顯式地按值捕獲. 其它變量按引用捕獲
[=, &z]   //z按引用捕獲. 其它變量按值捕獲

  接下來的兩個(gè)例子演示了Lambda表達(dá)式的用法.  

復(fù)制代碼
std::vector<int> some_list;
int total = 0;
for (int i=0;i<5;++i) some_list.push_back(i);
std::for_each(begin(some_list), end(some_list), [&total](int x) 
{
    total += x;
});
復(fù)制代碼

  此例計(jì)算list中所有元素的總和. 變量total被存為lambda函數(shù)閉包的一部分. 因?yàn)樗菞W兞?局部變量)total的引用,所以可以改變它的值.  

復(fù)制代碼
std::vector<int> some_list;
  int total = 0;
  int value = 5;
  std::for_each(begin(some_list), end(some_list), [&, value, this](int x) 
  {
    total += x * value * this->some_func();
  });
復(fù)制代碼

  此例中total會(huì)存為引用, value則會(huì)存一份值拷貝. 對(duì)this的捕獲比較特殊, 它只能按值捕獲. this只有當(dāng)包含它的最靠近它的函數(shù)不是靜態(tài)成員函數(shù)時(shí)才能被捕獲.對(duì)protect和priviate成員來說, 這個(gè)lambda函數(shù)與創(chuàng)建它的成員函數(shù)有相同的訪問控制. 如果this被捕獲了,不管是顯式還隱式的,那么它的類的作用域?qū)ambda函數(shù)就是可見的. 訪問this的成員不必使用this->語法,可以直接訪問.
  不同編譯器的具體實(shí)現(xiàn)可以有所不同,但期望的結(jié)果是:按引用捕獲的任何變量,lambda函數(shù)實(shí)際存儲(chǔ)的應(yīng)該是這些變量在創(chuàng)建這個(gè)lambda函數(shù)的函數(shù)的棧指針,而不是lambda函數(shù)本身?xiàng)W兞康囊? 不管怎樣, 因?yàn)榇髷?shù)lambda函數(shù)都很小且在局部作用中, 與候選的內(nèi)聯(lián)函數(shù)很類似, 所以按引用捕獲的那些變量不需要額外的存儲(chǔ)空間.
  如果一個(gè)閉包含有局部變量的引用,在超出創(chuàng)建它的作用域之外的地方被使用的話,這種行為是未定義的!
  lambda函數(shù)是一個(gè)依賴于實(shí)現(xiàn)的函數(shù)對(duì)象類型,這個(gè)類型的名字只有編譯器知道. 如果用戶想把lambda函數(shù)做為一個(gè)參數(shù)來傳遞, 那么形參的類型必須是模板類型或者必須能創(chuàng)建一個(gè)std::function類似的對(duì)象去捕獲lambda函數(shù).使用 auto關(guān)鍵字可以幫助存儲(chǔ)lambda函數(shù),  

auto my_lambda_func = [&](int x) { /*...*/ };
auto my_onheap_lambda_func = new auto([=](int x) { /*...*/ });

  這里有一個(gè)例子, 把匿名函數(shù)存儲(chǔ)在變量,數(shù)組或vector中,并把它們當(dāng)做命名參數(shù)來傳遞 

復(fù)制代碼
#include<functional>
#include<vector>
#include<iostream>
double eval(std::function<double(double)> f, double x = 2.0){return f(x);}
int main()
{
     std::function<double(double)> f0    = [](double x){return 1;};
     auto                          f1    = [](double x){return x;};
     decltype(f0)                  fa[3] = {f0,f1,[](double x){return x*x;}};
     std::vector<decltype(f0)>     fv    = {f0,f1};
     fv.push_back                  ([](double x){return x*x;});
     for(int i=0;i<fv.size();i++)  std::cout << fv[i](2.0) << "\n";
     for(int i=0;i<3;i++)          std::cout << fa[i](2.0) << "\n";
     for(auto &f : fv)             std::cout << f(2.0) << "\n";
     for(auto &f : fa)             std::cout << f(2.0) << "\n";
     std::cout << eval(f0) << "\n";
     std::cout << eval(f1) << "\n";
     return 0;
}
復(fù)制代碼

  一個(gè)沒有指定任何捕獲的lambda函數(shù),可以顯式轉(zhuǎn)換成一個(gè)具有相同聲明形式函數(shù)指針.所以,像下面這樣做是合法的:
 

auto a_lambda_func = [](int x) { /*...*/ };
void(*func_ptr)(int) = a_lambda_func;
func_ptr(4); //calls the lambda.

 

  
  
  

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多