C++0x:Lambda 按值捕获,始终是副本?

发布于 2024-10-21 07:13:34 字数 601 浏览 3 评论 0原文

编译器是否允许消除按值捕获所需的副本?

vector<Image> movie1;
apply( [=movie1](){ return movie1.size(); } );
  • 有没有什么情况编译器不需要复制movie1
    • 也许如果编译器知道,apply 实际上不会改变 movie1
    • 或者在任何情况下 Lambda 都默认为 const 函子,这是否有帮助?
  • vector 有一个移动构造函数移动赋值,这对完全有帮助吗?
    • 如果是,是否也需要将这些添加到 Image 中,以防止此处出现昂贵的副本?
  • 与按值参数捕获相比,按值捕获何时以及如何需要副本的机制是否存在差异?例如。 void opera(vector movie)?

Is the compiler allowed to eliminate the copy that is required for the by-value capture?

vector<Image> movie1;
apply( [=movie1](){ return movie1.size(); } );
  • Is there any circumstance that the compiler does not need to copy movie1?
    • Maybe if the compiler could know, that apply does not actually change movie1?
    • Or does it help that Lambdas are by default const functors in any case?
  • Does it help at all that vector has a move constructor and move assign?
    • If yes, is it required to add these to Image as well, to prevent an expensive copy here?
  • Is there a difference in the mechanism when and how a copy is required for by-value capture compared to by-value arguments? eg. void operate(vector<Image> movie)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓦然回首 2024-10-28 07:13:35

“假设”规则总是。只要看起来好像遵循了规则,编译器就可以做任何它喜欢做的事情。因此,对于复制构造函数和析构函数没有副作用的对象,并且没有对副本进行任何更改,或者之后不访问原始对象(因此如果我们对对象进行更改,没有人会注意到),编译器可以证明根据“假设”规则消除副本是合法的。

但除此之外,不,正如@Ben 所说,它不能仅仅消除副本。 “常规”复制省略规则不涵盖这种情况。

There is always the "as-if" rule. As long as it looks as if the rules had been followed, the compiler can do whatever it likes. So for objects where the copy constructor and destructor have no side effects, and where no changes are made to the copy, or the original object isn't accessed afterwards (so no one will notice if we make changes to the object), the compiler could prove that eliminating the copy is legal under the "as-if" rule.

But other than that, no, it can't just eliminate the copy, as @Ben said. The "regular" copy elision rules don't cover this case.

诗化ㄋ丶相逢 2024-10-28 07:13:34

我相当肯定它不能。

即使外部函数不再显式使用该变量,移动该变量也会改变破坏的语义。

Image 提供移动构造函数并没有帮助,vector 可以移动交换而不移动其元素。

如果变量从现在开始是只读的,为什么不通过引用捕获呢?您甚至可以创建一个常量引用并捕获它。

如果变量不是只读的,则需要副本。无论外部函数还是 lambda 执行修改,编译器都不能允许该修改对另一个函数可见。

我发现按值捕获和按值参数传递之间的唯一区别是捕获是命名的,它不能是临时的。因此不能使用适用于临时变量的参数传递优化。

I'm fairly sure it cannot.

Even if the outer function no longer explicitly uses the variable, moving the variable would change the semantics of destruction.

Having move constructors for Image doesn't help, a vector can move or swap without moving its elements.

If the variable is read-only from this point forward, why not capture by reference? You could even create a const reference and capture that.

If the variable is not read-only, the copy is required. It doesn't matter whether the outer function or the lambda performs the modification, the compiler cannot allow that modification to become visible to the other.

The only difference I see between by-value capture and by-value argument passing is that the capture is named, it cannot be a temporary. So argument passing optimizations applicable to temporaries cannot be used.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文