我想知道为什么我可以在lamdas中使用全局变量(感谢Chris Drew纠正我)以及为什么我不需要捕获它们:
#include <iostream>
#include <vector>
using namespace std;
size_t i = 0;
vector<int> v = {1,2,3};
int main()
{
auto lambda = [](){i = v.size();};
lambda();
cout << i << endl;
return EXIT_SUCCESS;
}
在这个最小的工作示例中,我访问size_t和向量而不捕获它们。如果它们在main方法中声明,我将不得不这样做。为什么会这样,我如何复制size_t和向量?我尝试使用[=]
作为捕获列表,但它不会复制v
和i
。
答案 0 :(得分:3)
按值捕获全局变量的一种方法是使用C ++ 14 generalized lambda captures:
#include <iostream>
#include <vector>
size_t i = 0;
std::vector<int> v = {1,2,3};
int main() {
auto lambda = [myi = i, myv = v]()mutable{myi = myv.size();};
lambda();
std::cout << i << std::endl;
}
答案 1 :(得分:2)
在您的情况下,i
和v
是全局变量,整个TU都可以访问。
当您询问如何按值捕获它们时,我认为您应该能够使用[=]
或列出变量[i, v]
捕获它们,但这会导致错误,因为它们会是只读的,你将分配给lambda体内的i
。
选项1:
通过ref和v来捕获i(如果这有意义的话......):
#include <iostream>
#include <vector>
using namespace std;
int main() {
size_t i = 0;
vector<int> v = {1,2,3};
auto lambda = [&i,v](){i = v.size();};
lambda();
cout << i << endl;
return EXIT_SUCCESS; }
选项2:
使用一个可变的lambda并按值捕获(这使得意义更小)
即see this question on SO。
请注意,在这种情况下,i
也会按值捕获,因此不会分配全局i
,保留值== 0。
答案 2 :(得分:2)
Lambdas可以访问全局变量和类中的静态变量,而无需显式捕获它们。如果它是一个局部变量,那么你的程序将是不正确的。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
size_t i = 0;
vector<int> v = {1,2,3};
auto lambda = [](){i = v.size();}; //Error,
lambda();
cout << i << endl;
return EXIT_SUCCESS;
}
见here
与类中的静态变量相同:
#include <iostream>
#include <vector>
using namespace std;
struct S{
void touch(){ []{ k = 89; }(); }
static int getK(){ return k; }
private:
static int k;
};
int S::k = 0;
int main()
{
S s;
std::cout << S::getK() << std::endl;
s.touch();
std::cout << S::getK() << std::endl;
}
见Here
答案 3 :(得分:2)
你的lambda基本上转换为仿函数,它与:
相同#include <iostream>
#include <vector>
using namespace std;
size_t i = 0;
vector<int> v = {1,2,3};
struct lambda
{
void operator()() { i = v.size(); }
};
int main()
{
lambda x;
x();
cout << i << endl;
return EXIT_SUCCESS;
}
正如您所看到的,lambda
可以完美地访问任何全局变量,甚至在其名称中,变量全局可访问。
如果i
和v
属于main()
的本地,那么我们就会遇到问题,我们必须抓住它们。