是否允许编译器消除按值捕获所需的副本?
vector<Image> movie1;
apply( [=movie1](){ return movie1.size(); } );
movie1
的情况?
apply
实际上不会改变 movie1
?const
仿函数是否有帮助?vector
有一个移动构造函数和移动分配,这对 有帮助吗?
Image
,以防止在此处出现昂贵的副本?void operate(vector<Image> movie)
?答案 0 :(得分:9)
我很确定它不能。
即使外部函数不再显式使用变量,移动变量也会改变破坏的语义。
移动Image
的构造函数没有帮助,vector
可以move
或swap
而不移动其元素。
如果变量从此时开始是只读的,为什么不通过引用捕获?你甚至可以创建一个const引用并捕获它。
如果变量不是只读变量,则需要复制。无论外部函数还是lambda执行修改都无关紧要,编译器不能允许该修改对另一个进行修改。
我在 by-value capture 和 by-value参数传递之间看到的唯一区别是捕获被命名,它不能是临时的。因此,不能使用适用于临时值的参数传递优化。
答案 1 :(得分:3)
总是“as-if”规则。只要它看起来好像遵循了规则,编译器就可以做任何喜欢的事情。因此,对于复制构造函数和析构函数没有副作用的对象,以及未对副本进行任何更改的对象,或者之后未访问原始对象(因此,如果我们对对象进行更改,则没有人会注意到),编译器可以证明根据“as-if”规则删除副本是合法的。
但除此之外,不,它不能只是消除副本,正如@Ben所说。 “常规”复制省略规则不包括此案例。