使用任一默认捕获模式时,这是通过复制捕获还是 (*this) 通过引用捕获?是同一回事吗?
When using either default capture mode, is this captured by copy or (*this) captured by reference? Is it the same thing?
看到下面工作的时候有点纳闷
struct A {
void g(){}
void f(){
[&](){ g(); }();
}
};
但后来我找到了 this
答案,其中非常详细地解释了它是如何工作的。
本质上归结为this
无论是用[=]
还是[&]
.[=35=都被值捕获了]
但是,在 cppreference 上,我阅读了以下内容
The current object (*this)
can be implicitly captured if either capture default is present. If implicitly captured, it is always captured by reference, even if the capture default is =
.
所以我有两个似乎等价的公式
this
无论我们使用[=]
还是[&]
. 都是按值捕获的
无论我们使用 [=]
还是 [&]
.,(*this)
都是通过引用捕获的
首先,以上两个公式是否完全等价?
我确实看到了两者之间的区别,即使不是在实际可行的方面,至少在它们看起来有多有用方面也是如此。
公式 1 对我来说似乎很奇怪。为什么阻止我通过 const
-reference 捕获 this
?在性能方面,这两种情况应该没有什么大的区别,我总是可以在 lambda 之前执行 auto const& This = this;
,然后通过引用捕获 This
,如果我愿意的话。关于悬挂引用,如果我使用 this
关键字,我在对象 class 中,那么当我在其中时对象怎么会死掉?
另一方面,公式 2 似乎确实可以保护我免于制作不必要的副本,如果 (*this)
在使用 [=]
时被值捕获,就会发生这种情况。此外,如果我真的想要,有一个捕获语法用于通过复制捕获 (*this)
,即 [*this]
.
First of all, are indeed the two formulations above perfectly equivalent?
您可以认为它们在功能上是相同的东西,但第二个并不是最好的思考方式。 this
总是按值捕获。但是正弦 this
是一个 指针 ,被捕获的值只是指向该对象的指针。所以你可以在概念上将其视为通过指针捕获通过引用指向的对象。
Why preventing me from capturing this by reference?
因为表达式 this
是纯右值。没有可以引用的名为 this
的对象。这就是为什么如果你 auto& This = this;
,你 get a compile error.
记住:this
是指向对象的指针。指针是纯右值; 指向的对象不是。
As regards dangling references, if I'm using the this keyword, I'm in the object class, so how can the object die while I'm inside it?
除了可以调用 this->~Typename()
来销毁对象之外,lambda 只是一个可调用对象。它可以持续存在于创建它的位置的边界之外。它可以被 returned(通过类型擦除,比如通过 std::function
或通过 auto
return 类型推导)或者它可以传递给其他人并存储在对象的范围。
第一个解释是 C++17 之前的意图(写那个答案的时候),但是 第二个 是之后的意图(正如当前的偏好)。本来认为this
(指针)是抓包的对象,当然不可能引用(如; const auto &x=…;
如果它引入一个临时的,则完全不是一回事)。 C++17 引入了捕获 *this
(按值),将现有捕获 [this]
重新解释为有效的 [&*this]
(这实际上不是有效语法)。
C++20 继续过渡,deprecating
struct A {
auto f() {return [=] {return this;}}
};
因为它实际上并没有按值捕获任何东西,相反 allowing [=,this]
现在被理解为“按值捕获所有东西 除了 对于 *this
”,而不是多余的“按值捕获所有内容,也按值 this
”。相反,[&,this]
现在应该被认为是 多余的 ,但它还没有被弃用(还)。
看到下面工作的时候有点纳闷
struct A {
void g(){}
void f(){
[&](){ g(); }();
}
};
但后来我找到了 this
答案,其中非常详细地解释了它是如何工作的。
本质上归结为this
无论是用[=]
还是[&]
.[=35=都被值捕获了]
但是,在 cppreference 上,我阅读了以下内容
The current object
(*this)
can be implicitly captured if either capture default is present. If implicitly captured, it is always captured by reference, even if the capture default is=
.
所以我有两个似乎等价的公式
this
无论我们使用[=]
还是[&]
. 都是按值捕获的
无论我们使用 (*this)
都是通过引用捕获的
[=]
还是 [&]
.,首先,以上两个公式是否完全等价?
我确实看到了两者之间的区别,即使不是在实际可行的方面,至少在它们看起来有多有用方面也是如此。
公式 1 对我来说似乎很奇怪。为什么阻止我通过 const
-reference 捕获 this
?在性能方面,这两种情况应该没有什么大的区别,我总是可以在 lambda 之前执行 auto const& This = this;
,然后通过引用捕获 This
,如果我愿意的话。关于悬挂引用,如果我使用 this
关键字,我在对象 class 中,那么当我在其中时对象怎么会死掉?
另一方面,公式 2 似乎确实可以保护我免于制作不必要的副本,如果 (*this)
在使用 [=]
时被值捕获,就会发生这种情况。此外,如果我真的想要,有一个捕获语法用于通过复制捕获 (*this)
,即 [*this]
.
First of all, are indeed the two formulations above perfectly equivalent?
您可以认为它们在功能上是相同的东西,但第二个并不是最好的思考方式。 this
总是按值捕获。但是正弦 this
是一个 指针 ,被捕获的值只是指向该对象的指针。所以你可以在概念上将其视为通过指针捕获通过引用指向的对象。
Why preventing me from capturing this by reference?
因为表达式 this
是纯右值。没有可以引用的名为 this
的对象。这就是为什么如果你 auto& This = this;
,你 get a compile error.
记住:this
是指向对象的指针。指针是纯右值; 指向的对象不是。
As regards dangling references, if I'm using the this keyword, I'm in the object class, so how can the object die while I'm inside it?
除了可以调用 this->~Typename()
来销毁对象之外,lambda 只是一个可调用对象。它可以持续存在于创建它的位置的边界之外。它可以被 returned(通过类型擦除,比如通过 std::function
或通过 auto
return 类型推导)或者它可以传递给其他人并存储在对象的范围。
第一个解释是 C++17 之前的意图(写那个答案的时候),但是 第二个 是之后的意图(正如当前的偏好)。本来认为this
(指针)是抓包的对象,当然不可能引用(如const auto &x=…;
如果它引入一个临时的,则完全不是一回事)。 C++17 引入了捕获 *this
(按值),将现有捕获 [this]
重新解释为有效的 [&*this]
(这实际上不是有效语法)。
C++20 继续过渡,deprecating
struct A {
auto f() {return [=] {return this;}}
};
因为它实际上并没有按值捕获任何东西,相反 allowing [=,this]
现在被理解为“按值捕获所有东西 除了 对于 *this
”,而不是多余的“按值捕获所有内容,也按值 this
”。相反,[&,this]
现在应该被认为是 多余的 ,但它还没有被弃用(还)。