#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
vector<std::function<bool(int)>> gv;
void myfunc() {
srand((unsigned)time(nullptr));
int tempvalue = rand() % 6;
gv.push_back(
//[&](int tv) {
[=](int tv) {
if(tv % tempvalue == 0) { // 如果tv是tmpvalue的倍数
return true;
}
return false;
}
);
}
void myfunc_static() {
static int tempvalue = 4; // 静态变量不需要捕获,也捕获不到
gv.push_back(
//[&](int tv) {
[](int tv) {
cout << "static tempvalue:" << tempvalue << endl;
if(tv % tempvalue == 0) { // 如果tv是tmpvalue的倍数
return true;
}
return false;
}
);
++tempvalue;
}
class AT {
public:
int m_tempvalue = 10;
void addItem() {
gv.push_back(
//[&](int tv) {
//=是按值捕获的意思
//我们会认为这个[=]是按值捕获,使我们能够访问成员变量m_tempvalue
//所以我们顺理成章的认为,这里这个lambda表达式所用的m_tempvalue是按值捕获
//[=](auto tv) { //=等价于有this
//[=](int tv) { //=等价于有this.用了=用了&就默认等于添加了this
[this](int tv) {
//[&](int tv) {
cout << "m_tempvalue: " << m_tempvalue << endl; // this->m_tempvalue
if(tv % m_tempvalue == 0) { // this->m_tempvalue
return true;
}
return false;
}
);
int tmpvalueCopy = m_tempvalue;
gv.push_back(
[=](int tv) {
cout << "tmpvalueCopy: " << tmpvalueCopy << endl; // this->m_tempvalue
if(tv % tmpvalueCopy == 0) {
return true;
}
return false;
}
);
gv.push_back(
[abc = m_tempvalue](int tv) {
cout << "abc: " << abc << endl;
if(tv % abc == 0) {
return true;
}
return false;
}
);
}
};
int main() {
//一:捕获列表中的&:捕获外部作用域中所有变量,并作为引用在lambda表达式中使用;
//按照引用这种捕获方式,或导致lambda表达式包含绑定到局部变量的引用
myfunc();
cout << gv[0](10) << endl; // 非法调用,会产生不可预料的问题
//二:形参列表可以使用auto
//c++14允许在lambda表达式的形参列表中使用auto
//引用捕获方式超出反问的情形也叫做“引用悬空",采用按值捕获的方式可以解决这个问题
//三:成员变量的捕获问题
AT* pat = new AT();
//pat->m_tempvalue = 90;
pat->addItem();
pat->m_tempvalue = 90; // 放在这里并不会修改tmpvalueCopy的数值,没有修改副本,也就是gv[3]
// 这里会修改gv[2]中的m_tempvalue数值,因为它和this绑定
delete pat; // 这里删除gv[2]就没有办法使用了,因为他和this->m_tempvalue绑定
// 结论:lambda表达式的执行结果正确与否,取决于pat对象是否存在,
// 只有pat对象存在,这个lambda表达式执行才正确
// 我们大家首先要明确一点:捕获这个概念,只针对在创建lambda表达式的作用域内可见的
// 非静态局部变量(包括形参)
// m_teempvalue并不是非静态局部变量,m_tempvalue是AT类的成员变量,成员变量是不能被捕获到的
// this:指向本身,所以这里你用[=]捕获的是this指针值
//cout << gv[1](10) << endl;
cout << gv[2](10) << endl;
// 四:广义lambda捕获:c++14:generalized lambda capture:
cout << gv[3](10) << endl;
// 五:静态局部变量:捕获这种事,是不包含静态局部变量的,也就是说静态局部变量是不能被捕获的
// 但是可以在lambda使用,另外静态局部变量是保存在静态存储区,它的有效期一直到程序结束
// 但是这种对static变量的使用有点类型按照引用捕获的效果
myfunc_static();
cout << gv[4](10) << endl;
myfunc_static();
cout << gv[5](10) << endl;
return 0;
}