在C ++ 11中,RVO会优化以这种风格编写的代码吗?

时间:2013-08-04 21:51:27

标签: optimization c++11

我在成长过去的时候长大,因为它们往往很大,因此它们通常很大,因此指针总是要走的路。既然C ++ 11具有相当不错的RVO(正确的值优化),我想知道以下代码是否有效。

正如你所看到的,我的类有一堆矢量结构(不是它们的指针)。构造函数接受值结构并将它们存储起来。

My -hope-是编译器将使用移动语义,以便确实没有复制正在进行的数据;构造函数将(在可能的情况下)承担传入的值的所有权。

有谁知道这是否属实,并且是自动发生的,还是我需要一个带有&&的移动构造函数?语法等等?

// ParticleVertex
//
// Class that represents the particle vertices

class ParticleVertex : public Vertex
{
  public:
    D3DXVECTOR4   _vertexPosition;
    D3DXVECTOR2   _vertexTextureCoordinate;
    D3DXVECTOR3   _vertexDirection;
    D3DXVECTOR3   _vertexColorMultipler;

    ParticleVertex(D3DXVECTOR4   vertexPosition,
                   D3DXVECTOR2   vertexTextureCoordinate,
                   D3DXVECTOR3   vertexDirection,
                   D3DXVECTOR3   vertexColorMultipler)
    {
        _vertexPosition          = vertexPosition;
        _vertexTextureCoordinate = vertexTextureCoordinate;
        _vertexDirection         = vertexDirection;
        _vertexColorMultipler    = vertexColorMultipler;
    }

    virtual const D3DVERTEXELEMENT9 * GetVertexDeclaration() const
    {
        return particleVertexDeclarations;
    }
};

2 个答案:

答案 0 :(得分:0)

是的,确实你应该相信编译器能够最佳地“移动”结构:

  

指南:不要复制你的函数参数。相反,按值传递它们,让编译器进行复制

在这种情况下,您将参数移动到构造函数调用中:

ParticleVertex myPV(std::move(pos),
               std::move(textureCoordinate),
               std::move(direction),
               std::move(colorMultipler));

在许多情况下,std::move隐式,例如

D3DXVECTOR4 getFooPosition() { 
     D3DXVECTOR4 result;
     // bla

     return result; // NRVO, std::move only required with MSVC
}

ParticleVertex myPV(getFooPosition(), // implicit rvalue-reference moved

答案 1 :(得分:0)

RVO 表示返回值优化不是正确的值优化。

RVO是当函数返回值时由编译器执行的优化,并且它清楚地表明代码返回在正文中创建的临时对象,因此可以避免复制。该函数直接返回创建的对象。

C ++ 11引入的是 Move Semantics 。移动语义允许我们将资源从某个临时对象“移动”到目标对象 但是,移动意味着资源来自的对象在移动后处于不可用状态。这不是你想要的类(我认为),因为顶级数据是由类使用的,即使用户是否调用了这个函数。 因此,使用const引用的公共返回来避免复制。

另一方面,DirectX提供资源(指针)的句柄,而不是真实资源。指针是基本类型,它的复制很便宜,所以不要担心性能。在您的情况下,您使用2d / 3d向量。它的复制也很便宜。

就个人而言,我认为返回指向内部资源的指针总是一个非常糟糕的主意。我认为在这种情况下,最好的方法是通过const引用返回。