C++ Lambda作二分查找谓词时未设捕获默认值的隐式捕获报错
报错成因
这个编译提示对应的问题完全来自C++ Lambda的捕获规则:
- 你当前写的Lambda在捕获列表里只显式抓了
comparisons这个变量 - 但Lambda的函数体里直接用了外面定义的
searchValue局部变量 - 按照C++标准,没有写捕获默认(比如
[&]/[=])的Lambda,必须把所有要引用的局部外部变量全部列在捕获列表里,编译器不会帮你自动隐式抓取没声明的变量,碰到这种漏写的情况就会抛出这个错误。
可直接使用的修正方法
按照你的代码场景,有三种改法都能解决问题:
- 最规范的精准改法:在Lambda捕获列表里补上缺失的
searchValue,因为这里只需要拿它的固定值做相等判断,按值捕获就行,没有生命周期风险,也不会抓多余的变量:auto iter = my::binary_search2(std::begin(data), std::end(data), searchValue, [&comparisons, searchValue](int& num) { ++comparisons; return num == searchValue; } ); - 代码量小的时候的偷懒改法:直接开启引用类的默认捕获,自动把当前作用域里Lambda用到的所有外部变量按引用抓进来:
这种写法胜在写起来快,缺点是如果Lambda逻辑变复杂,可能会不小心捕获到根本不需要的变量,引入不必要的耦合。auto iter = my::binary_search2(std::begin(data), std::end(data), searchValue, [&](int& num) { ++comparisons; return num == searchValue; } ); - 贴合现有模板逻辑的优化方向:你写的
binary_search2本身已经接收了待查找的value参数,其实完全没必要让外层Lambda手动捕获searchValue——本来相等判断就是拿当前遍历的元素和传入的查找值对比,把这部分逻辑放到binary_search2内部处理的话,连Lambda的捕获都能省掉,代码会更干净。
内容的提问来源于stack exchange,提问作者BrownBear2018
相关产品推荐
相关产品推荐

