C++11ラmda表現はシーン解析を使用します.

4749 ワード

ランバー表現の使用シーン
実はlambankを使い始めたばかりの時から気になりましたが、いつ使えばいいですか?使わなくてもいい時によく使います.本当に余計です.じゃ、どのような場合に使いますか?lambankda表現は匿名関数と呼ばれるので(もちろん、名前のないインライン関数としても理解できます)、関数と関係があります.普通はプログラミングする時にこのコードを一つの関数に入れて呼び出します.この時は関数名を考えられなくなります.名前を取るのは本当に面倒くさいことがあります.突然の短絡で命の名前がわからなくなることがありますが、この時はlamda表現を思い出してください.命名困難症という問題をうまく解決してくれます.また、どのような場合にはlamband表現を使うかを考えてもいいですか?あなたのプロジェクト全体のプログラミングでは、関数が独立して出てきますが、この関数は比較的簡単で、プロジェクト全体で一回しか使われていないかもしれません.つまり、この時はlamda表現を使用することを考慮します.コードをよりコンパクトにして、メンテナンスしやすくすることができます.
Lamda表現の簡単な応用
まず、lamda式変数の切り取り方法を見てください.
  • []は、いかなる変数も傍受しない
  • [&]は、外部作用領域におけるすべての変数を傍受し、参照として関数体に
  • を使用する.
  • [=]外部作用領域におけるすべての変数を傍受し、関数体に
  • を使用するコピーを行う.
  • (=、&foo)は、外部作用領域のすべての変数を傍受し、1つのコピーを関数に使用しますが、foo変数に対しては参照
  • を使用します.
  • [bar]Bar変数を切り取り、関数体重で使用するコピーを行います.他の変数
  • を切り取りません.
  • [this]は、現在のクラスのthisポインタを切り取ります.既に使用している場合は、このオプションをデフォルトで追加します.
  • シーン1:
    私たちはアルゴリズムの問題をする時、よく一つの問題に出会います.二つの数の大きさを比較して、一番目の数が二番目の数より大きい時にtrueに戻ります.逆にfalseに戻ります.
    まず私たちの伝統的な解決方法を書きます.
    #include 
    #include 
    #include 
    
    using namespace std;
    
    bool compare(int& a, int& b)
    {
        return a > b;
    }
    
    int main(void)
    {
        int data[6] = { 3, 4, 12, 2, 1, 6 };
        vector testdata;
        testdata.insert(testdata.begin(), data, data + 6);
        
        //     
        sort(testdata.begin(), testdata.end(), compare);    //   
    
        return 0;
    }
    
    このコードはあまりにも簡単だと思いませんでしたが、名前をつけました.名前は関数全体の大部分のアルファベットを占めています.でも、心配しないでください.私達はlamda表現があります.はい、私達のlamda表現の解法を見てみます.
    #include 
    #include 
    #include 
    
    using namespace std;
    
    int main(void)
    {
        int data[6] = { 3, 4, 12, 2, 1, 6 };
        vector testdata;
        testdata.insert(testdata.begin(), data, data + 6);
    
        sort(testdata.begin(), testdata.end(), [](int a, int b){ return a > b; });
    
        return 0;
    }
    
    シーン2
    autを使用してlamband表現を受信することもできますが、もちろんC+11の中の新しい特性functionを直接使用してlamband表現を受信することもできます.両者は同等です.autは自動タイプ変換なので、いくつかの場合に使いやすいです.
    *暖かいヒント:*functionをよく知らない読者はインターネットで関連資料を検索できます.functionの頭ファイルは「functional」です.
    #include 
    #include 
    using namespace std;
    
    int main(void)
    {
        int x = 8, y = 9;
        auto add = [](int a, int b) { return a + b; };
        std::function Add = [=](int a, int b) { return a + b; };
    
        cout << "add: " << add(x, y) << endl;
        cout << "Add: " << Add(x, y) << endl;
    
        return 0;
    }
    
    最終的な運転結果は、17解析:functionの最初のintは戻り値タイプ、括弧の中の二つのintは関数のパラメータタイプです.
    シーン3
    この再帰的アルゴリズムをLambada表現を用いて大まかに説明します.これはf(1)=1、f(2)=2が知られていますが、f(n)=f(n−1)+f(n−2)を実現してください.ここのn>2は明らかな再帰的アルゴリズムではないですか?簡単すぎます
    #include 
    #include 
    using namespace std;
    
    int main(void)
    {
        std::function recursion = [&recursion](int n) { 
    		return n < 2 ? 1 : recursion(n - 1) + recursion(n - 2); 
    	};
    
        //            
    	cout << "recursion(2):" << recursion(2) << endl;
    	cout << "recursion(3):" << recursion(3) << endl;
    	cout << "recursion(4):" << recursion(4) << endl;
    
        return 0;
    }
    
    実行結果:
    recursion(2):2  
    recursion(3):3  
    recursion(4):5 
    
    なぜここではautを使わないのですか?エラーが発生しますので、aut型引数を使って宣言する変数が自分の初期値設定項目に現れないようにヒントを与えます.個人的にはautは自動タイプの変換であるため、上記の例のようにlamda式の戻り値でrecursionのタイプを確認する必要があります.ですから、ここでautoを使ってエラーを報告します.ここは私個人の理解です.個人の能力は限られていますので、このような解釈が正しいかどうかは分かりません.
    補足:場面四
    実際にコードを作成すると、以下のような場合があります.ここで疑似コードを使います.
    void TestFun()
    {
    	int a, b, c;
    	.....	//          
    
    	if (  1)
    	{
    		//                  
    		//     a、b、c....    
    	}
    	if (  2)
    	{
    		//                  
    		//     a、b、c....    
    	}
    	if (  3)
    	{
    		//                  		
    		//     a、b、c....    
    	}
    }
    
    実際に作成中にこのような状況に遭遇した場合(条件ごとに同じまたは類似のコードブロックを呼び出し、コードブロック内に関数内の変数が大量に使用されています.)、Lamdaを使用したことがない場合、最初の時間は関数呼び出し、またはマクロ(マクロはここでは言いません)を考慮することができますが、関数呼び出しを使用する場合は以下のような問題が考えられます.
    1、コードブロックに使用されている変数の山は全部参照によって伝達されますか?2、もしあのパラメータの中にいくつかのパラメータが追加されていて、コードブロックが全部使われているなら、関数を参照インターフェースに変えて、呼出するところを変えますか?
    上の二つの問題から感じられます.普通の関数の呼び出しはちょっと煩わしいです.じゃ、私達はlamda表現を考えます.上の疑似コードを次のように書き換えます.
    void TestFun()
    {
    	int a, b, c;
    	.....	//          
    
    	//           &  =    &  =          
    	// param      lambda      
    	auto lambdaFun = [&](int param) -> void {
    		//           TestFun    
    		//   a、b、c....    
    	}
    
    	if (  1)
    	{
    		lambdaFun(param1);
    	}
    	if (  2)
    	{
    		lambdaFun(param2);
    	}
    	if (  3)
    	{
    		lambdaFun(param3);
    	}
    }
    
    lambadaの呼び出しによって、複雑だと思っていたパラメータ問題を簡単に解決できます.続きは他にもいいシーンがあれば更新し続けます.