C+11返回值优化还是移动?

C+11返回值优化还是移动?

我不明白什么时候该用std::move当我应该让编译器优化.。例如:

using SerialBuffer = vector< unsigned char >;// let compiler optimize itSerialBuffer read( size_t size ) const{
    SerialBuffer buffer( size );
    read( begin( buffer ), end( buffer ) );
    // Return Value Optimization
    return buffer;}// explicit moveSerialBuffer read( size_t size ) const{
    SerialBuffer buffer( size );
    read( begin( buffer ), end( buffer ) );
    return move( buffer );}

我该用哪一种?


手掌心
浏览 698回答 3
3回答

慕无忌1623718

只使用第一种方法:Foo&nbsp;f(){ &nbsp;&nbsp;Foo&nbsp;result; &nbsp;&nbsp;mangle(result); &nbsp;&nbsp;return&nbsp;result;}这将已经允许使用移动构造函数(如果可用的话)。实际上,局部变量可以绑定到return当允许复制省略时,精确地声明。您的第二个版本积极禁止复制省略。第一个版本普遍更好。

慕森卡

所有返回值都已经moved或者优化出,因此不需要显式地使用返回值移动。编译器允许自动移动返回值(优化副本),甚至优化移动!N 3337标准草案第12.8节(C+11):当满足某些条件时,即使对象的复制/移动构造函数和/或析构函数有副作用,也允许实现省略类对象的复制/移动构造。在这种情况下,实现将省略的复制/移动操作的源和目标简单地视为引用同一个对象的两种不同方式,而该对象的销毁发生在如果不进行优化就会销毁这两个对象的后期。复制省略,允许在下列情况下(可合并以消除多份副本):[...]例:class&nbsp;Thing&nbsp;{public:Thing(); &nbsp;&nbsp;&nbsp;~Thing(); &nbsp;&nbsp;&nbsp;Thing(const&nbsp;Thing&);};Thing&nbsp;f()&nbsp;{ &nbsp;&nbsp;&nbsp;Thing&nbsp;t; &nbsp;&nbsp;&nbsp;return&nbsp;t;}Thing&nbsp;t2&nbsp;=&nbsp;f();在这里,可以将省略的条件组合起来,以消除对类的复制构造函数的两个调用。Thing*复制本地自动对象t到函数返回值的临时对象中。f()以及将该临时对象复制到对象中。t2..有效地,局部对象的构造t可以被视为直接初始化全局对象。t2,该物体的破坏将发生在程序出口。向Thing具有相同的效果,但它是从临时对象移动到t2那是被剥夺的。-终例&nbsp;]如果符合或将满足复制操作的省略条件,除非源对象是函数参数,并且要复制的对象由lvalue指定,则首先执行重载解析,以选择副本的构造函数,就好像该对象是由rvalue指定的一样。如果重载解析失败,或者所选构造函数的第一个参数的类型不是对象类型的rvalue引用(可能是cv限定的),则再次执行重载解析,将对象视为lvalue。

万千封印

很简单。return buffer;如果你这样做,那么NRVO要么会发生,要么就不会发生。如果它不发生,那么buffer将被移出。return std::move( buffer );如果你这么做,那么NVRO不会发生,而且buffer将被移出。所以使用std::move在这里,还有很多损失。这条规则有一个例外:Buffer&nbsp;read(Buffer&&&nbsp;buffer)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//... &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;std::move(&nbsp;buffer&nbsp;);}如果buffer是一个rvalue引用,那么您应该使用std::move..这是因为引用不符合NRVO的条件,所以没有std::move它将产生一个来自lvalue的副本。这只是“永远”这条规则的一个实例。movervalue引用和forward“通用引用”,优先于“从不”的规则。move返回值“。
打开App,查看更多内容
随时随地看视频慕课网APP