91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++中lambda和function如何使用

發布時間:2022-08-10 09:22:14 來源:億速云 閱讀:139 作者:iii 欄目:開發技術

今天小編給大家分享一下C++中lambda和function如何使用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

lambda表達式

lambda表達式又稱為匿名表達式,是C11提出的新語法。[]存儲lambda表達式要捕獲的值,()內的參數為形參,可供外部調用傳值。lambda表達式可以直接調用

 // 1  匿名調用
    [](string name)
    {
        cout << "this is anonymous" << endl;
        cout << "hello " << name << endl;
    }("zack");

上述代碼定義了一個匿名函數后直接調用。我們可以通過auto初始化一個變量存儲lambda表達式

 // 2 通過auto賦值
    auto fname = [](string name)
    {
        cout << "this is auto  " << endl;
        cout << "hello " << name << endl;
    };
    fname("Rolin");

通過auto定義fname,然后存儲了lambda表達式,之后調用fname即可。也可以通過函數指針的方式接受lambda表達式

    typedef void (*P_NameFunc)(string name);
    // 3 函數指針
    P_NameFunc fname2 = [](string name)
    {
        cout << "this is P_NameFunc " << endl;
        cout << "hello " << name << endl;
    };
    fname2("Vivo");

P_NameFunc定義了fname2函數指針接受了lambda表達式。也可以通過function對象接受lambda表達式,function類是C11新增的語法。

// 4 function
    function<void(string)> funcName;
    funcName = [](string name)
    {
        cout << "this is function " << endl;
        cout << "hello " << name << endl;
    };
    funcName("Uncle Wang");

用一個function對象接受了lambda表達式,同樣可以調用該function對象funcName達到調用lambda的效果。

談談lambda的捕獲

1 值捕獲

    int age = 33;
    string name = "zack";
    int score = 100;
    string job = "softengineer";
    //值捕獲
    [age, name](string name_)
    {
        cout << "age is " << age << " name is " << name << " self-name is " << name_ << endl;
    }("Novia");

上述lambda表達式捕獲了age和name,是以值的方式來捕獲的。所以無法在lambda表達式內部修改age和name的值,如果修改age和name,編譯器會報錯,提示無法修改const常量,因為age和name是以值的方式被捕獲的。

2 引用捕獲

    int age = 33;
    string name = "zack";
    int score = 100;
    string job = "softengineer";
    [&age, &name](string name_)
    {
        cout << "age is " << age << " name is " << name << " self-name is " << name_ << endl;
        name = "Xiao Li";
        age = 18;
    }("Novia");

[]里age和name前邊添加了&,此時age和name是以引用方式捕獲的。所以可以在lambda表達式中修改age和name的值。

C++的lambda表達式雖然可以捕獲局部變量的引用,達到類似閉包的效果,但不是真的閉包,golang和python等語言通過閉包捕獲局部變量后可以增加局部變量的聲明周期,C++無法做到這一點,所以下面的調用會出現崩潰。

vector<function<void(string)>> vec_Funcs;
void use_lambda2()
{
    int age = 33;
    string name = "zack";
    int score = 100;
    string job = "softengineer";
    vec_Funcs.push_back([age, name](string name_)
                        {   cout << "this is value catch " << endl;
                            cout << "age is " << age << " name is " << name << " self-name is " << name_ << endl; });
    //危險,不要捕獲局部變量的引用
    vec_Funcs.push_back([&age, &name](string name_)
                        {   cout << "this is referenc catch" << endl;
                            cout << "age is " << age << " name is " << name << " self-name is " << name_ << endl; });
}
void use_lambda3()
{
    for (auto f : vec_Funcs)
    {
        f("zack");
    }
}
int main(){
    use_lambda2();
    use_lambda3();
}

use_lambda2中將lambda表達式存儲在function類型的vector里,當use_lambda2結束后,里邊的局部變量都被釋放了,而vector中的lambda表達式還存儲著局部變量的引用,在調用use_lambda3時調用lambda表達式,此時訪問局部變量已經被釋放了,所以導致程序崩潰。

3 全部用值捕獲,name用引用捕獲

    int age = 33;
    string name = "zack";
    int score = 100;
    string job = "softengineer";
    [=, &name]()
    {
        cout << "age is " << age << " name is " << name << " score is " << score << " job is " << job << endl;
        name = "Cui Hua";
    }();

通過=表示所有變量都以值的方式捕獲,如果希望某個變量以引用方式捕獲則單獨在這個變量前加&。

4 全部用引用捕獲,只有name用值捕獲

   int age = 33;
   string name = "zack";
   int score = 100;
   string job = "softengineer";
   [&, name]()
   {
        cout << "age is " << age << " name is " << name << " score is " << score << " job is " << job << endl;
   }();

通過&方式表示所有變量都已引用方式捕獲,如果希望某個變量以值方式捕獲則單獨在這個變量前加=。

萬能的function

我們可以用function存儲形參和返回值相同的一類函數指針,可調用對象,lambda表達式等。

void use_function()
{
    list<function<void(string)>> list_Funcs;
    //存儲函數對象
    list_Funcs.push_back(FuncObj());
    //存儲lambda表達式
    list_Funcs.push_back([](string str)
                         { cout << "this is lambda call " << str << endl; });
    //存儲全局函數
    list_Funcs.push_back(globalFun);
    for (const auto &f : list_Funcs)
    {
        f("hello zack");
    }
}

bind操作

C11同樣提供了bind操作,將原函數的幾個參數通過bind綁定傳值,返回一個新的可調用對象。

    //綁定全局函數
    auto newfun1 = bind(globalFun2, placeholders::_1, placeholders::_2, 98, "worker");
    //相當于調用globalFun2("Lily",22, 98,"worker");
    newfun1("Lily", 22);
    //多傳參數沒有用,相當于調用globalFun2("Lucy",28, 98,"worker");
    newfun1("Lucy", 28, 100, "doctor");
    auto newfun2 = bind(globalFun2, "zack", placeholders::_1, 100, placeholders::_2);
    //相當于調用globalFun2("zack",33,100,"engineer");
    newfun2(33, "engineer");
    auto newfun3 = bind(globalFun2, "zack", placeholders::_2, 100, placeholders::_1);
    newfun3("coder", 33);

placeholders表示占位符,_1表示新生成函數的第一個參數, _2表示新生成函數的第二個參數,將這些參數傳遞給原函數達到占位的效果,原函數的其余參數通過bind綁定固定值。

接下來定義類

class BindTestClass
{
public:
    BindTestClass(int num_, string name_) : num(num_), name(name_) {}
    static void StaticFun(const string &str, int age);
    void MemberFun(const string &job, int score);
public:
    int num;
    string name;
};

實現靜態函數和成員函數

void BindTestClass::StaticFun(const string &str, int age)
{
    cout << "this is static function" << endl;
    cout << "name is " << str << endl;
    cout << "age is " << age << endl;
}
void BindTestClass::MemberFun(const string &job, int score)
{
    cout << "this is member function" << endl;
    cout << "name is " << name << endl;
    cout << "age is " << num << endl;
    cout << "job is " << job << endl;
    cout << "score is " << score << endl;
}

我們通過bind綁定靜態成員函數

    //綁定類的靜態成員函數,加不加&都可以
    // auto staticbind = bind(BindTestClass::StaticFun, placeholders::_1, 33);
    auto staticbind = bind(&BindTestClass::StaticFun, placeholders::_1, 33);
    staticbind("zack");

新生成的staticbind函數可以直接傳遞一個參數zack就完成了調用。接下來用bind綁定成員函數

    BindTestClass bindTestClass(33, "zack");
    // 綁定類的成員函數,一定要傳遞對象給bind的第二個參數,可以是類對象,也可以是類對象的指針
    // 如果要修改類成員,必須傳遞類對象的指針
    auto memberbind = bind(BindTestClass::MemberFun, &bindTestClass, placeholders::_1, placeholders::_2);
    memberbind("coder", 100);
    auto memberbind2 = bind(BindTestClass::MemberFun, placeholders::_3, placeholders::_1, placeholders::_2);
    memberbind2("coder", 100, &bindTestClass);
    //綁定類成員時,對象必須取地址
    auto numbind = bind(&BindTestClass::num, placeholders::_1);
    std::cout << numbind(bindTestClass) << endl;

當然也可以直接用function對象接受bind返回的結果

    // function接受bind返回的函數
    function<void(int, string)> funcbind = bind(globalFun2, "zack", placeholders::_1, 100, placeholders::_2);
    funcbind(33, "engineer");
    // function接受bind 成員函數
    function<void(string, int)> funcbind2 = bind(BindTestClass::MemberFun, &bindTestClass, placeholders::_1, placeholders::_2);
    funcbind2("docker", 100);
    function<void(string, int, BindTestClass *)> funcbind3 = bind(BindTestClass::MemberFun, placeholders::_3, placeholders::_1, placeholders::_2);
    funcbind3("driver", 100, &bindTestClass);
    // function 直接接受成員函數,function的模板列表里第一個參數是類對象引用
    function<void(BindTestClass &, const string &, int)> functomem = BindTestClass::MemberFun;
    functomem(bindTestClass, "functomem", 88);
    // function 綁定類的靜態成員函數
    function<void(const string &)> funbindstatic = bind(&BindTestClass::StaticFun, placeholders::_1, 33);
    funbindstatic("Rolis");

以上就是“C++中lambda和function如何使用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

通化市| 达尔| 阿城市| 阿瓦提县| 安顺市| 贵定县| 蓬安县| 阿城市| 祥云县| 垦利县| 逊克县| 菏泽市| 隆化县| 民丰县| 宜宾市| 阿拉善左旗| 崇义县| 离岛区| 丰县| 淳安县| 新田县| 报价| 佳木斯市| 社旗县| 福安市| 丽江市| 临朐县| 沂源县| 南涧| 德格县| 安远县| 抚顺市| 张家口市| 永仁县| 腾冲县| 金坛市| 历史| 开原市| 普定县| 庆云县| 福贡县|