C++ は関数内で関数を定義します

C++ では関数内で関数を定義することもできますか? これは不可能ですが、関数オブジェクトを定義することは可能です。従来の方法で関数オブジェクトを定義すると、関数クラスを自分で記述する必要があり、不便です。しかし、C++11のリリース後は、関数内に「関数」(実際には「関数オブジェクト」)を簡単に定義できるようになりました。

Part.I の例

以下は簡単な例で、main関数内で 2 つの「関数オブジェクト」が定義されており、1 つはprint 2 次元ベクトルを出力するために使用され、もう 1 つは、cmpsort 関数のソート基準を提供するために使用されます。 2番目の要素のサイズ 大きいものから小さいものへ並べます。

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main()
{
    
    
    auto print = [](vector<vector<int>> a) {
    
    
        for(int i=0;i<a.size();i++) {
    
    
            for(int j=0;j<a[i].size();j++)
                cout<<a[i][j]<<" ";
            cout<<endl;
        }
    };
    vector<vector<int>> A;
    vector<int> B({
    
    1,2}); A.push_back(B);
    B=vector<int>({
    
    2,1}); A.push_back(B);
    B=vector<int>({
    
    3,6}); A.push_back(B);
    cout<<"----------Origin---------"<<endl;
    print(A);
    auto cmp = [](const vector<int> a, const vector<int> b){
    
    return a[1]>b[1];};
    sort(A.begin(), A.end(), cmp);
    cout<<"----------After Sorted---------"<<endl;
    print(A);
    getchar();
    return 0;
}

結果の出力は次のようになります。

----------Origin---------
1 2
2 1
3 6
----------After Sorted---------
3 6
1 2
2 1

第Ⅱ部 説明

この文言の説明:

  • 上記のコードは、古い標準の自動変数 (スペースの自動割り当てと自動解放) の意味ではなく、C++ 11 では新しい機能を持っています。変数が宣言されると、変数の初期化値autoから導出され、変数の型の値を指定します。
  • auto print = [](xx) { };は のないラムダ式です-> ret。ラムダ式については後で詳しく紹介します。
  • Lambda は名前のない関数オブジェクトを生成するため、関数内で直接呼び出すことはできません。ただし、「この名前のない関数オブジェクトにエイリアスを付ける」と、エイリアスを介して呼び出すことができます。

第 I 章 ラムダ式

参考:http://c.biancheng.net/view/3741.html

ラムダは関数型プログラミングの概念から派生したもので、最新のプログラミング言語の機能です。C++11 ではついにラムダが追加されました。

ラムダ式には次の利点があります。

  • 宣言型プログラミング スタイル: 追加の名前付き関数または関数オブジェクトを作成せずに、ターゲット関数または関数オブジェクトを匿名でその場で定義します。可読性と保守性に優れた、より直接的な方法でプログラムを作成します。
  • 簡潔さ: 追加の関数や関数オブジェクトを記述する必要がないため、コードの拡張や関数の分散が回避され、開発者は当面の問題により集中できるようになり、生産性も向上します。
  • 必要なときに必要な場所に関数クロージャを実装すると、プログラムがより柔軟になります。

ラムダ式は匿名関数を定義し、特定のスコープ内の変数をキャプチャできます。ラムダ式の文法形式は次のように簡単に要約できます。

[ capture ] ( params ) opt -> ret {
    
     body; };

  • Capture はキャプチャ リスト、空は変数がキャプチャされないことを意味します。&外側のスコープ内のすべての変数をキャプチャし、関数本体内の参照として使用することを意味します (参照によるキャプチャ)。=外側のスコープ内のすべての変数をキャプチャして使用することを意味します。 (値によるキャプチャ) で使用される関数本体内のコピーとして;=,&foo外側のスコープ内のすべての変数を値によってキャプチャし、foo変数を参照によってキャプチャすることを意味します。他の変数をキャプチャせずに、barvalue によって変数をキャプチャすることは、ラムダ式が現在のクラスのメンバー関数と同じアクセス権を持つように、現在のクラスの this ポインターをキャプチャすることを意味します。または がすでに使用されている場合、このオプションはデフォルトで追加されます。これをキャプチャする目的は、lamda で現在のクラスのメンバー関数とメンバー変数を使用することです。barthis&=
  • params はパラメータリストです。
  • opt は関数のオプションです。
  • ret は戻り値の型です。
  • body は関数本体です

おすすめ

転載: blog.csdn.net/Gou_Hailong/article/details/127860552