能否对Lambda的初始化捕获进行默认初始化?
能否对Lambda的初始化捕获进行默认初始化?
当然可以!不过得看你用的C版本——C20及以后的标准直接支持这种操作,咱们结合你的代码场景来具体说。
先看你原来的代码,nums是外部数组,通过引用捕获到Lambda里,还要靠reinitNums控制初始化逻辑。其实你可以把这两个变量都封装到Lambda内部,用初始化捕获来处理,代码会更紧凑也更封装。
C++20的实现方式(推荐)
C++20新增了默认初始化的捕获语法,你可以直接指定类型让Lambda帮你默认初始化变量,效果和你在外部直接声明变量完全一致。修改后的代码大概是这样:
const auto lambda{ [nums: std::array<int, 10>, reinitNums = true] (auto&&... args) mutable { // 第一次调用或需要重新初始化时填充nums if (reinitNums) { // 这里写你的初始化逻辑,比如给nums赋值 nums.fill(42); // 举个例子,替换成你实际的初始化代码 reinitNums = false; } // 这里使用nums做你需要的操作 for (int num : nums) { std::cout << num << " "; } std::cout << "\n"; // 满足条件时标记需要重新初始化 if (some_condition) { // 替换成你的实际判断条件 reinitNums = true; } } };
这里要注意几个点:
[nums: std::array<int, 10>]就是默认初始化捕获,和你写std::array<int,10> nums;的效果一样——数组元素是未初始化的(和你原来的代码逻辑一致),所以你还是要在reinitNums为true时手动填充值。- 因为Lambda里要修改
nums和reinitNums,必须加上mutable关键字,不然Lambda默认是const属性,没法修改捕获的变量。
C++20之前的替代方案
如果你的编译器还不支持C++20,那只能用显式的初始化表达式来捕获,但要注意细节:
- 如果你写
[nums = std::array<int,10>{}],这是值初始化,会把数组所有元素置为0,和你原来代码里的未初始化状态不一样。 - 要是想保持未初始化的状态,C++20之前可以捕获一个默认构造的临时对象,但其实这也是值初始化(元素会被置0):
const auto lambda{ [nums = std::array<int,10>(), reinitNums = true] (auto&&... args) mutable { // 后面的逻辑和上面一致 } };
如果真的需要完全未初始化的数组,C20之前可能只能把nums设为Lambda内部的静态变量,但这样会导致Lambda不是线程安全的,所以还是尽量升级到C20更省心。
备注:内容来源于stack exchange,提问作者Nil Admirari
相关产品推荐
相关产品推荐

