欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++如何向Lambda傳遞參數(shù)與捕獲

 更新時間:2025年03月26日 10:17:44   作者:愚戲師  
文章介紹了C++中向Lambda表達式傳遞參數(shù)和使用捕獲列表的基本規(guī)則和示例,參數(shù)傳遞要求嚴(yán)格匹配類型和數(shù)量,而捕獲列表允許Lambda訪問外部變量,并可以按值或引用捕獲,文章還討論了捕獲的陷阱和解決方案,以及參數(shù)傳遞與捕獲列表的區(qū)別和應(yīng)用場景,感興趣的朋友一起看看吧
介紹向Lambda傳遞參數(shù)與捕獲列表相關(guān)內(nèi)容

?一、向Lambda傳遞參數(shù)

?核心規(guī)則

Lambda的參數(shù)傳遞機制與普通函數(shù)類似,但有以下嚴(yán)格限制:

  • ?無默認(rèn)參數(shù):Lambda不支持默認(rèn)參數(shù),必須顯式傳遞所有參數(shù)。
  • ?參數(shù)嚴(yán)格匹配:實參與形參的數(shù)量、類型必須完全一致。 ?

示例1:Lambda替代isShorter函數(shù)

// 原比較函數(shù)
bool isShorter(const string &a, const string &b) {
    return a.size() < b.size();
}
// 用Lambda實現(xiàn)相同功能
vector<string> words = {"apple", "banana", "cherry", "date"};
stable_sort(words.begin(), words.end(), 
            [](const string &a, const string &b) { 
                return a.size() < b.size(); 
            });

關(guān)鍵點

  • Lambda形參ab的類型必須與容器元素類型一致(此處為const string&)。
  • stable_sort每次比較時會自動傳遞兩個元素給Lambda。

?二、捕獲列表:訪問外部變量的橋梁

?捕獲的本質(zhì)

Lambda通過捕獲列表訪問所在函數(shù)的局部變量,而非全局變量或靜態(tài)變量。

  • ?按值捕獲:創(chuàng)建變量的副本,Lambda內(nèi)部修改不影響外部變量。?
  • 按引用捕獲:直接操作外部變量,需注意變量生命周期。 ?

示例2:捕獲局部變量實現(xiàn)條件篩選

#include <vector>
#include <string>
#include <algorithm>
// 過濾字符串向量,找到第一個長度大于或等于指定大小的字符串
std::vector<std::string>::const_iterator filterWords(const std::vector<std::string> &words, size_t sz) {
    // 捕獲 sz,按值傳遞(隱式拷貝),用于查找第一個長度 >= sz 的字符串
    auto it = std::find_if(words.begin(), words.end(),
                           [sz](const std::string &s) { 
                               return s.size() >= sz; 
                           });
    return it; // 返回找到的字符串的迭代器
}
int main() {
    std::vector<std::string> words = {"apple", "banana", "cherry", "date"};
    size_t sz = 6;
    auto result = filterWords(words, sz);
    if (result != words.end()) {
        std::cout << "找到第一個長度 >= " << sz << " 的字符串: " << *result << std::endl;
    } else {
        std::cout << "未找到長度 >= " << sz << " 的字符串。" << std::endl;
    }
    return 0;
}

關(guān)鍵點

  • szfilterWords函數(shù)的局部變量,必須顯式捕獲才能被Lambda使用。
  • 此處按值捕獲sz,Lambda內(nèi)部使用的是捕獲時的副本。

?三、捕獲方式詳解

?1. 顯式捕獲(Explicit Capture)?

明確指定要捕獲的變量及方式:

  • ?按值捕獲:[var]?
  • 按引用捕獲:[&var] ?

示例3:按引用捕獲動態(tài)更新值

#include <iostream>
#include <vector>
#include <algorithm>
/**
 * @brief 主函數(shù),程序的入口點。
 * 
 * 該函數(shù)創(chuàng)建一個整數(shù)向量,使用 std::count_if 統(tǒng)計向量中偶數(shù)的數(shù)量,并輸出結(jié)果。
 * 
 * @return int 程序的退出狀態(tài)碼,0 表示正常退出。
 */
int main() {
    // 定義一個整數(shù)向量 nums,并初始化其元素
    std::vector<int> nums = {1, 2, 3, 4};
    // 定義一個變量 count,用于存儲偶數(shù)的數(shù)量,初始化為 0
    int count = 0;
    // 使用 std::count_if 統(tǒng)計向量中偶數(shù)的數(shù)量
    // std::count_if 接受三個參數(shù):向量的起始迭代器、結(jié)束迭代器和一個謂詞函數(shù)
    // 謂詞函數(shù)是一個 lambda 表達式,用于判斷元素是否為偶數(shù)
    count = std::count_if(nums.begin(), nums.end(), [&count](int x) {
        // 判斷元素 x 是否為偶數(shù)
        return x % 2 == 0;
    });
    // 輸出偶數(shù)的數(shù)量
    std::cout << count << std::endl; // 輸出2(統(tǒng)計偶數(shù)的數(shù)量)
    // 返回 0 表示程序正常結(jié)束
    return 0;
}

關(guān)鍵點

  • 使用&count按引用捕獲,Lambda內(nèi)部修改會影響外部變量。
  • count在Lambda調(diào)用前被銷毀(如局部變量),會導(dǎo)致懸空引用。

?2. 隱式捕獲(Implicit Capture)?

通過[=][&]批量捕獲變量:

  • [=]:按值捕獲所有外部變量。
  • [&]:按引用捕獲所有外部變量。

?示例4:隱式捕獲簡化代碼

int threshold = 5;
vector<int> data = {3, 7, 2, 8};
// 隱式按值捕獲所有外部變量(此處只有threshold)
auto result = count_if(data.begin(), data.end(),
                      [=](int x) { 
                          return x > threshold; 
                      });
cout << result; // 輸出2(7和8大于5)

?3. 混合捕獲(Mixed Capture)?

結(jié)合顯式和隱式捕獲,但需注意優(yōu)先級:

  • [=, &var]:按值捕獲所有變量,但var按引用捕獲。
  • [&, var]:按引用捕獲所有變量,但var按值捕獲。

?示例5:混合捕獲實現(xiàn)靈活訪問

int base = 10;
double factor = 1.5;
vector<int> values = {3, 5, 7};
// 按引用捕獲base,按值捕獲其他變量
for_each(values.begin(), values.end(),
        [&base, factor](int &x) {
            x = base + x * factor; 
        });
// 結(jié)果:base=10 → 10+3 * 1.5=14.5 → 轉(zhuǎn)為int為14
// 最終values變?yōu)閇14, 17, 20]

?四、捕獲的陷阱與解決方案

?陷阱1:懸空引用(Dangling Reference)?

當(dāng)Lambda捕獲的引用變量在調(diào)用前被銷毀時,引發(fā)未定義行為。

#include<iostream>
// 引入輸入輸出流庫,使得程序可以使用 std::cout 進行輸出操作
using namespace std;
// 使用標(biāo)準(zhǔn)命名空間,這樣可以直接使用標(biāo)準(zhǔn)庫中的對象和函數(shù),而無需加 std:: 前綴
auto createLambda() {
    // 定義一個函數(shù) createLambda,使用 auto 讓編譯器自動推導(dǎo)返回類型
    int localVar = 42;
    // 在函數(shù)內(nèi)部定義一個局部變量 localVar,并初始化為 42
    return [&localVar] { return localVar; }; 
    // 返回一個 lambda 表達式,該 lambda 表達式通過值捕獲了局部變量 localVar
}
int main() {
    // 程序的入口函數(shù)
    auto lambda = createLambda();
    // 調(diào)用 createLambda 函數(shù),將返回的 lambda 表達式賦值給變量 lambda
    cout << lambda(); 
    // 調(diào)用 lambda 表達式,由于 lambda 表達式通過值捕獲了 localVar 的副本,所以可以正常輸出 42
    return 0;
    // 程序正常結(jié)束,返回 0
}

解決方案

#include<iostream>
// 引入輸入輸出流庫,使得程序可以使用 std::cout 進行輸出操作
using namespace std;
// 使用標(biāo)準(zhǔn)命名空間,這樣可以直接使用標(biāo)準(zhǔn)庫中的對象和函數(shù),而無需加 std:: 前綴
auto createLambda() {
    // 定義一個函數(shù) createLambda,使用 auto 讓編譯器自動推導(dǎo)返回類型
    int localVar = 42;
    // 在函數(shù)內(nèi)部定義一個局部變量 localVar,并初始化為 42
    return [localVar] { return localVar; }; 
    // 返回一個 lambda 表達式,該 lambda 表達式通過值捕獲了局部變量 localVar
    // 值捕獲會在創(chuàng)建 lambda 表達式時復(fù)制一份 localVar 的副本,即使原變量被銷毀,副本仍然有效
}
int main() {
    // 程序的入口函數(shù)
    auto lambda = createLambda();
    // 調(diào)用 createLambda 函數(shù),將返回的 lambda 表達式賦值給變量 lambda
    cout << lambda(); 
    // 調(diào)用 lambda 表達式,由于 lambda 表達式通過值捕獲了 localVar 的副本,所以可以正常輸出 42
    return 0;
    // 程序正常結(jié)束,返回 0
}

?陷阱2:修改按值捕獲的變量

默認(rèn)情況下,按值捕獲的變量在Lambda內(nèi)不可修改。

int x = 10;
auto lambda = [x] { 
    x++; // 編譯錯誤:按值捕獲的變量不可修改
};

解決方案:使用mutable關(guān)鍵字允許修改副本。

auto lambda = [x]() mutable { 
    x++; // 修改的是副本,不影響外部x
};

?陷阱3:捕獲this指針(類成員訪問)?

在類成員函數(shù)中,Lambda需捕獲this才能訪問成員變量。

class Processor {
private:
    int offset;
public:
    void process(vector<int> &data) {
        for_each(data.begin(), data.end(),
                [this](int &x) { x += offset; }); // 正確捕獲this
    }
};

五、捕獲與參數(shù)傳遞對比

?特性?參數(shù)傳遞?捕獲列表
?數(shù)據(jù)來源調(diào)用時傳入的實參所在函數(shù)的局部變量
?生命周期由調(diào)用者管理按值捕獲:與Lambda生命周期一致;
按引用捕獲:依賴原變量生命周期
?修改權(quán)限形參可修改(除非聲明為const按值捕獲:需mutable;
按引用捕獲:直接修改原變量
?典型場景比較、轉(zhuǎn)換等需要動態(tài)數(shù)據(jù)的場景條件篩選、狀態(tài)保持等需要外部變量的場景

?六、小結(jié)

  • ?參數(shù)傳遞:用于Lambda處理動態(tài)輸入數(shù)據(jù),需嚴(yán)格匹配類型和數(shù)量。?
    • 捕獲列表: 按值捕獲([var]):適合只讀訪問或需要副本的場景。
    • 按引用捕獲([&var]):適合需要修改外部變量或避免拷貝的場景,但需警惕懸空引用。
    • 混合捕獲([=, &var]):靈活平衡性能與安全性。 ?
  • 核心準(zhǔn)則:優(yōu)先最小化捕獲范圍,避免隱式捕獲(如[=][&]),顯式聲明更安全。

到此這篇關(guān)于C++如何向Lambda傳遞參數(shù)與捕獲的文章就介紹到這了,更多相關(guān)C++ Lambda傳遞參數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)簡易版掃雷游戲

    C++實現(xiàn)簡易版掃雷游戲

    大家好,本篇文章主要講的是C++實現(xiàn)簡易版掃雷游戲,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • Qt實現(xiàn)簡易QQ聊天界面

    Qt實現(xiàn)簡易QQ聊天界面

    這篇文章主要為大家詳細介紹了Qt實現(xiàn)簡易QQ聊天界面,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C語言實現(xiàn)括號匹配的方法

    C語言實現(xiàn)括號匹配的方法

    這篇文章主要介紹了C語言實現(xiàn)括號匹配的方法,文中代碼簡單易懂,方便大家更好的學(xué)習(xí),感興趣的朋友可以參考下
    2020-06-06
  • C++中與輸入相關(guān)的istream類成員函數(shù)簡介

    C++中與輸入相關(guān)的istream類成員函數(shù)簡介

    這篇文章主要介紹了C++中與輸入相關(guān)的istream類成員函數(shù)簡介,包括eof函數(shù)和peek函數(shù)以及putback函數(shù)還有ignore函數(shù),需要的朋友可以參考下
    2015-09-09
  • C語言庫函數(shù)qsort的使用詳解

    C語言庫函數(shù)qsort的使用詳解

    C語言庫函數(shù)中的qsort的是一個回調(diào)函數(shù),回調(diào)函數(shù)就是一個通過函數(shù)指針調(diào)用的函數(shù),這篇文章主要介紹了C語言庫函數(shù)qsort的使用,需要的朋友可以參考下
    2022-06-06
  • 使用C語言實現(xiàn)字符串左旋和右旋問題

    使用C語言實現(xiàn)字符串左旋和右旋問題

    這篇文章主要介紹了使用C語言實現(xiàn)字符串左旋和右旋問題,需要的朋友可以參考下
    2018-07-07
  • C++實現(xiàn)下載的代碼

    C++實現(xiàn)下載的代碼

    這篇文章主要介紹了C++實現(xiàn)下載的代碼,以下載百度圖片為例較為完整的講述了C++下載的具體實現(xiàn)方法,需要的朋友可以參考下
    2014-10-10
  • 詳解次小生成樹以及相關(guān)的C++求解方法

    詳解次小生成樹以及相關(guān)的C++求解方法

    這篇文章主要介紹了詳解次小生成樹以及相關(guān)的C++求解方法,文中的練習(xí)示例采用了kruskal算法通過C++進行求解,需要的朋友可以參考下
    2015-08-08
  • Unity編輯器下重啟的方法

    Unity編輯器下重啟的方法

    這篇文章主要介紹了Unity編輯器下重啟的方法的相關(guān)資料,希望通過本文能幫助到大家,讓大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • 基于QT實現(xiàn)顯示OpenCV讀取的圖片

    基于QT實現(xiàn)顯示OpenCV讀取的圖片

    OpenCV自帶了一部分常用的GUI功能,但是更多的圖像處理功能需要其他GUI框架來輔助實現(xiàn),本文將通過QT來顯示OpenCV讀取的圖片,需要的可以參考一下
    2022-11-11

最新評論