C++ 在类中使用时,lambda捕获列表中的[this]和[&;]是否等效?
在下面的示例中,在捕获列表中使用[this]与在捕获列表中使用引用捕获[&]有什么区别,如图所示?我试过这两种方法,结果都是一样的C++ 在类中使用时,lambda捕获列表中的[this]和[&;]是否等效?,c++,lambda,C++,Lambda,在下面的示例中,在捕获列表中使用[this]与在捕获列表中使用引用捕获[&]有什么区别,如图所示?我试过这两种方法,结果都是一样的 #include <iostream> class Test { public:
#include <iostream>
class Test {
public:
int x = 2;
void test1(void) { std::cout << "test1" << std::endl; };
void test_lambda(void) {
auto lambda = [&] () {
std::cout << "x: " << x << " y: " << y << " z: " << z << std::endl;
this->test1();
};
lambda();
}
protected:
int y = 3;
private:
int z = 4;
};
int main() {
Test t;
t.test_lambda();
}
这似乎意味着它们可能意味着同一件事。如果是这样,为什么我们需要这个?这个
&
通过引用捕获范围内的所有变量。考虑这一点:
void test_lambda(void) {
int dummy = 42; // capture dummy ?!?
auto lambda = [&] () { // yes
std::cout << "x: " << x << " y: " << y << " z: " << z << std::endl;
this->test1();
std::cout << dummy; // ok here
};
lambda();
}
void test_lambda(void){
int dummy=42;//捕获dummy?!?
自动lambda=[&](){//是
标准::cout根据:
[&]通过引用捕获lambda主体中使用的所有自动变量,如果存在,则通过引用捕获当前对象
然而,使用[this]将仅捕获此
指针
当范围中有自动变量时,这将有所不同,例如:
struct Test {
void run() {
int y = 2;
// all automatic variables are accessible, both local and members
auto l1 = [&](){ cout << x << " " << y << endl; };
l1();
// y is not accessible, x is only because it's a member
auto l2 = [this]() { cout << this->x << endl; };
l2();
}
int x = 1;
};
int main() {
Test t;
t.run();
}
struct测试{
无效运行(){
int y=2;
//所有自动变量都可以访问,包括本地变量和成员变量
自动l1=[&](){cout捕获成员的唯一方法是捕获此:
- 显式地
[this](){member=42;}
- 隐式地通过值捕获
[=](){member=42;}
- 通过引用捕获隐式地
[&](){member=42;}
以下是非法的
[&member](){member=42;}//非法
[member](){std::cout使用[this]
将仅捕获此
,而[&]
从封闭范围捕获此
和所有局部变量
struct example {
int foo;
example() {
int bar;
[this]() {
foo = {};
bar = {}; // error: 'bar' is not captured
}();
[&]() {
foo = {};
bar = {};
}();
}
};
如果将在封闭范围之外调用闭包(如成员函数),则可以使用[this]
,因为所有局部变量都将被销毁
struct example {
int value = 42;
example() {
frobnicate = [this]() {
std::cout << value << std::endl;
};
}
std::function<void ()> frobnicate;
};
example x;
x.frobnicate();
问题是“既然[&]
比[这个]
更强大,为什么我们需要[这个]
@因为你不想捕捉那些你不想捕捉的东西capture@RaymondChen鉴于这不在问题中,且问题未经编辑,您从何处获得此引用?我阅读此引用的方式与tobi303相同,即询问它们是否相等,如果不相等,它们之间的差异如何。最后一个问题总结了I问题:“如果是这样的话,为什么我们需要[这个]
?”换句话说,“如果[&]
和[这个]
,为什么我们甚至有[这个]
?”@RaymondChen最后一个问题是“如果是这样的话,为什么我们需要[这个]?”而“如果是这样的话”指的是[&]
和[这个]
意思是一样的。在我的回答中,我试图解释为什么这是错误的。而且我没有看到任何“令人敬畏的”…&可以用于特定变量始终使用您可以使用的最不强大的捕获。这不仅使局部推理更容易,而且您还可以避免偶尔出现错误:“性能”,cppreference中的引用意味着只捕获使用过的变量。这对性能没有影响,因为如果捕获的变量少于此值,编译将失败。我没有检查标准,因此这可能是编译器扩展或其他内容,但根据经验,[&member=member](){/*…*/}
工作正常。@DanielH:这声明了一个由变量初始化的“命名lambda成员”。我不会说它是该成员的捕获(同样,对于auto&ref=member;[&ref](){/*…*/}
),对我来说,这只是一个初始化。无论哪种方式,它都被称为捕获,在本例中,它是对同一变量的引用。我不知道捕获和引用初始化之间有什么区别;有没有两种情况表现不同?@DanielH:in[toto=42](){std::我同意,这看起来很奇怪,但我认为这仍然是一个技术术语。我的意思是,当x
是非成员变量名时,[&x=x]
和[&x]
之间的行为有区别吗?如果没有,那么[&member=member]
应该等同于捕获成员
,即使它不是完全相同的东西。
struct example {
int value = 42;
example() {
frobnicate = [this]() {
std::cout << value << std::endl;
};
}
std::function<void ()> frobnicate;
};
example x;
x.frobnicate();
struct example {
int value = 42;
example() {
int values[] = {1, 2, 3};
std::for_each(std::begin(values), std::end(values), [&](int& v) {
std::cout << v * value << std::endl;
});
}
};