c – 何时应该在函数返回值上使用std :: move?

c – 何时应该在函数返回值上使用std :: move?,第1张

概述参见英文答案 > c++11 Return value optimization or move?                                     4个 在这种情况下 struct Foo {};Foo meh() { return std::move(Foo());} 我很确定移动是不必要的,因为新创建的Foo将是一个xvalue. 但在这种情况下呢? struc 参见英文答案 > c++11 Return value optimization or move?                                     4个
在这种情况下

struct Foo {};Foo meh() {  return std::move(Foo());}

我很确定移动是不必要的,因为新创建的Foo将是一个xvalue.

但在这种情况下呢?

struct Foo {};Foo meh() {  Foo foo;  //do something,but kNowing that foo can safely be disposed of  //but does the compiler necessarily kNow it?  //we may have references/pointers to foo. how Could the compiler kNow?  return std::move(foo); //so here the move is needed,right?}

我认为需要采取行动吗?

解决方法 在返回std :: move(foo)的情况下;由于12.8 / 32,此举是多余的:

When the criteria for elision of a copy operation are met or would be
met save for the fact that the source object is a function parameter,
and the object to be copIEd is designated by an lvalue,overload
resolution to select the constructor for the copy is first performed as
if the object were designated by an rvalue.

回归foo;是NRVO的案例,因此允许复制省略. foo是一个左值.因此,从foo到meh的返回值选择“复制”的构造函数必须是移动构造函数(如果存在).

但是添加move确实会产生一些潜在的影响:它可以防止移动被省略,因为返回std :: move(foo);没有资格获得NRVO.

据我所知,12.8 / 32列出了左移的副本可以被移动替换的唯一条件.一般情况下,编译器不允许在复制后检测左值未使用(比如使用DFA),并自行进行更改.我在这里假设两者之间存在可观察到的差异 – 如果可观察行为相同则应用“假设”规则.

因此,要回答标题中的问题,请在需要移动时使用std :: move返回值,并且无论如何都不会移动它.那是:

>你希望它被移动,并且
>这是一个左值,而且
>它不符合复制条款的条件,并且
>它不是按值函数参数的名称.

考虑到这是非常繁琐而且移动通常很便宜,您可能会说在非模板代码中您可以简化这一点.使用std :: move时:

>你希望它被移动,而且
>你不能担心它.

通过遵循简化的规则,你牺牲了一些移动省略.对于像std :: vector这样的类型,移动成本很低,你可能永远不会注意到(如果你注意到你可以优化).对于像std :: array这样移动成本昂贵的类型,或者对于你不知道移动是否便宜的模板,你更可能会担心它.

总结

以上是内存溢出为你收集整理的c – 何时应该在函数返回值上使用std :: move?全部内容,希望文章能够帮你解决c – 何时应该在函数返回值上使用std :: move?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1224645.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存