将lambda绑定到转发引用

huangapple go评论90阅读模式
英文:

Binding lambda to forwarding reference

问题

绑定到带有 auto&& 的 lambda 是安全的吗?也就是说,lambda 的生命周期会延长到转发引用的生命周期吗?为什么/为什么不?

auto&& fn = ;

我怀疑应该是安全的。据我了解,lambda 表达式应该是 prvalue 表达式,然后 auto&& 转发引用应该变成一个右值引用。右值引用在某些条件下应该会延长临时对象的生命周期。但在这里,我不太确定 lambda 是否符合这些条件。

英文:

Is it safe to bind to a lambda with auto&&? I.e will the lifetime of the lambda be extended to the lifetime of the forwarding reference? Why / why not?

auto&& fn = <lambda declaration>;

I suspect that it should be. As far as I understand, lambda expressions are supposed to be prvalue expressions, and the auto&& forwarding reference should then become an rvalue reference. rvalue references are supposed to extend the lifetime of temporaries, at least under certain conditions. But here I'm not quite sure if the lambda qualifies.

答案1

得分: 2

是的,是和不是。

不,它并不像你说的那样危险。

是的,使用 auto&& 绑定到 lambda 是安全的,并且不危险,因为临时对象在定义语句结束后并不会被销毁。发生的情况是,右值引用延长了其生命周期(就像你说的那样),但只会在引用本身被销毁时,也就是超出作用域时才会被销毁。所以,你说它延长了生命周期是正确的,但并不会以危险的方式来做。

引用 Scott Meyers,在他详细阐述的**《Effective Modern C++》**中提到:

auto 的类型推导规则与模板相同(除了一个例外:auto 中的花括号被解释为 std::initializer_lists)。

另外,在这个问题上,使用 auto&& 声明 lambda,它始终是一个纯函数,因此如果从左值初始化,则它是一个左值引用,如果从右值初始化,则是一个右值引用。由于 lambda 是纯右值,它成为了右值引用,允许它延长其生命周期,但只会在引用本身被销毁时,也就是超出作用域时才会被销毁。

英文:

Short answer. Yes and no.
<br>
No, it is not dangerous as you say.
Yes, it is safe to bind to a lambda with auto&&, and is not dangerous, because the temporary object isn't destroyed after the end of the definition statement. What happens is that the rvalue reference extends its lifetime (yes like you said) but only until the reference itself gets destroyed, when it is out of scope. So, you are right that it extends the lifetime, but does not do it in such a way that is dangerous.
<br>

To quote Scott Meyers, as he elaborates in Effective Modern C++:
> The rules for type deduction of auto are the same as those of
> templates (apart from one exception: curly braces in auto are
> interpreted as std::initializer_lists).

Also, relating to this matter, declaring a lambda, which is always a pure function, with auto&amp;&amp; is a forwarding reference, thus it is an lvalue reference if initialized from an lvalue and an rvalue reference if initialized from an rvalue. Since lambdas are pure rvalue, it becomes an rvalue reference, which allows it to extend its lifetime but only until the reference itself gets destroyed, when it is out of scope.

huangapple
  • 本文由 发表于 2023年7月3日 23:22:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76606134.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定