Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.lang.c++.moderated    |    Moderated discussion of C++ superhackery    |    33,346 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 32,575 of 33,346    |
|    Gene Bushuyev to All    |
|    Re: rvalue references and parameter pass    |
|    05 Oct 12 23:28:07    |
   
   From: publicfilter@gbresearch.com   
      
   { Reformatted; please limit your lines to 70 characters,   
    and do not insert empty lines in quoted sections. -mod }   
      
   On Tuesday, October 2, 2012 4:23:30 PM UTC-7, fmatthew5876 wrote:   
   > Suppose I have this:   
   >   
   > class Matrix4 {   
   > public:   
   > //stuff   
   > private:   
   > float _m[16];   
   > };   
   >   
   > Matrix4 operator+(Matrix4 l, const Matrix4& r) {   
   > l += r;   
   > return l;   
   > }   
      
   The Matrix4 class has no move semantics, built-in types are always   
   copied. But assuming you modified it to make use of moves (simplified   
   version):   
      
   class Matrix4 {   
    float* m;   
   public:   
    Matrix4() : m(new float[16]) {}   
    Matrix4(const Matrix4& other) : m(new float[16])   
    { std::copy(other.m, other.m+16, m); std::cout << "\ncopy"; }   
    Matrix4(Matrix4&& other) : m(other.m) { other.m = 0; std::cout <<   
   "\nmove"; }   
    ~Matrix4() { delete[] m; }   
    Matrix4& operator+= (const Matrix4& other)   
    {   
    for(auto i = 0; i < 16; ++i) { m[i] += other.m[i]; }   
    return *this;   
    }   
   };   
      
   Matrix4 operator+ (Matrix4 l /* move from temporary*/, const Matrix4& r)   
   {   
    std::cout << "\noperator+(Matrix4, const Matrix4&)";   
    // move explicitly, because += returns lvalue reference   
    return std::move(l += r);   
   }   
      
   Unfortunately this solution is not general enough, it only handles the   
   cases of lvalue+lvalue, rvalue+lvalue, rvalue+rvalue, but   
   lvalue+rvalue is inefficient. The following overload takes care of   
   lvalue+rvalue case (Matrix&& has higher priority than const Matrix& in   
   selecting best viable function):   
      
   Matrix4 operator+ (const Matrix4& l, Matrix4&& r)   
   {   
    std::cout << "\nnoperator+(const Matrix4&, Matrix4&&)";   
    return std::move(r += l); // move explicitly   
   }   
      
   Here you can find the test: http://ideone.com/XV6BY   
   >   
   > Is there any possible scenario where I would want to also create   
   > a version of operator+ that uses rvalue references? i.e.   
   >   
   > Matrix4 operator+(Matrix4 l, const Matrix4&& r) {   
   > l+=r;   
   > return l;   
   > }   
      
   No reason to create this one, it doesn't do anything different.   
      
      
   --   
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
    [ comp.lang.c++.moderated. First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca