c++ - C ++ Lambda谓词原因变量不能在没有指定捕获默认值的lambda中隐式捕获
问题描述
这是函数定义
template<typename Iter, typename T>
Iter lower_bound(Iter left, Iter right, const T& value){
while (left < right){
auto mid = std::next(left, std::distance(left, right)/2);
if (*mid < value){
left = std::next(mid);
}else{
right = mid;
}
}
return left;
}
template<typename Iter, typename T, typename Predicate>
Iter binary_search2(Iter left, Iter right, const T& value, Predicate funct){
auto it = my::lower_bound(left, right, value);
if (it != right && funct(*it)){
return it;
}else{
return right;
}
}
函数应该类似于 {return *it == value}; 所以我想我会在 main 方法中使用一个 lambda 函数,如下所示:
auto searchValue = 10;
int comparisons = 0; // see how many comparison made
auto iter = my::binary_search2(std::begin(data), std::end(data), searchValue, [&comparisons](int& num){
++comparisons;
return num == searchValue;
});
我收到一个奇怪的错误“无法在未指定捕获默认值的 lambda 中隐式捕获 searchValue”
有任何想法吗?
解决方案
想想像这样的 lambda
auto x = [](int a) -> int {
return a + 2;
};
就像
struct Lambda {
int operator()(int a) const{
return a + 2;
}
};
这里
x(1) == Lambda{}(1) // == 3
现在,如果想从 lambda 上下文之外捕获一个额外的变量:
int y = 5;
auto x = [y](int a) -> int {
return a + y;
};
这大致相当于
struct Lambda {
explicit Lambda2(int y): y(y){}
int operator()(int a) const{
return a + y;
}
private:
int y;
};
因此,现在
x(1) == Lambda{y} // == 6
第二种情况是所谓的捕获 Lambda,因为,嗯……它从其范围之外捕获变量。需要为 lambda(或大致等效的结构)提供它需要捕获的变量列表,以供以后调用时使用。
有很多方法可以捕获变量。对于您的问题,一种方法可能是按值捕获变量,因为它是一个普通整数
auto iter = my::binary_search2(std::begin(data), std::end(data), searchValue,
[&comparisons, searchValue](int& num){
++comparisons;
return num == searchValue;
});
searchValue
传递变量的副本。这有点像第二个版本的struct Lambda
使用方式。
另一种方法是通过引用来捕获它,以防searchValue
一个具有昂贵副本的变量或者想要在 lambda 主体中修改它。[这大致相当于传入了对构造函数的引用struct Lambda
]
auto iter = my::binary_search2(std::begin(data), std::end(data), searchValue,
[&comparisons, &searchValue](int& num){
++comparisons;
return num == searchValue;
});
如果您想通过引用捕获但不希望在 lambda 主体中对其进行修改,那么可以执行类似的操作
auto iter = my::binary_search2(std::begin(data), std::end(data), searchValue,
[&comparisons, &constSV = std::as_const(searchValue)](int& num){
++comparisons;
return num == constSV;
});
通过使用std::as_const
来获取对捕获变量的 const 引用。这相当于将 a 传递const&
给 的构造函数struct Lambda
。
这些是一些可以使用的捕获类型。
推荐阅读
- python - 为什么我的 for 循环试图从标题行而不是第一行开始?
- mysql - 带有 MySQL 数据库的 Docker Spring Boot,连接被拒绝
- sql - 改进查询以减少重复
- python - 张量流动物园模型对象检测 - 大小会影响结果吗?
- sql - 将 PostgreSQL 查询转换为 SQL Server 查询
- javascript - 状态更改时重新呈现导航栏
- python - ModuleNotFoundError:没有名为“模型”的模块并且都是正确的
- sql - 在雪花的 PIVOT 期间保持多行
- c - 将页面预取到 RAM
- python - 在不使用列表的情况下计算 10 个整数之间的最大增量