Thread: move semantics / rvalue references

  1. #1
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838

    move semantics / rvalue references

    just now looking into this. not sure if i'm doign it wrong. a sanity check would be much appreciated.

    Code:
    Matrix&& Matrix::operator +(const Matrix& b)const
    {
        Matrix result(*this);
        result+=b;
        return (Matrix&&)result;
    }
    
    Matrix::Matrix(Matrix&& rhs):
       data(rhs.data),
       rows(rhs.rows),
       cols(rhs.cols)
    {
    }
    
    void foo()
    {
       Matrix a;
       Matrix b;
       Matrix aPlusB(a+b);
    }
    edit: ok it seems like i am definitely missing the point. this is the usage case i'd like to accomodate: using arithmetic operators on matrix operations without any extraneous copies. if someone can assist in disabusing me of my ignorance that would be fantastic.

    thanks.
    Last edited by m37h0d; 12-08-2011 at 09:31 AM.

  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    the addition operator is often implemented as a free function, and as a friend to the class upon which it acts.

    also, instead of copying or moving *this, you should just create a local reference like so:
    Code:
    Matrix& result = *this;

  3. #3
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    i don't really get what you're saying...result is a new matrix and i don't want to modify this

  4. #4
    Registered User
    Join Date
    Aug 2003
    Posts
    127
    Code:
    Matrix::Matrix(Matrix&& rhs):
       data(std::move(rhs.data)),
       rows(std::move(rhs.rows)),
       cols(std::move(rhs.cols))
    {
    }
    
    Matrix aPlusB(a+b); //aPlus is moved from the temp object.
    Nana C++ Library is a GUI framework that designed to be C++ style, cross-platform and easy-to-use.

  5. #5
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    evidently return (Matrix&&)result still returns a dangling reference - that seems to be the problem. is RVO sufficient to optimize this usage case? what i'm reading seems to suggest it is. i've previously noticed that neither the copy ctor nor the assignment operator is invoked, so that would make sense

  6. #6
    Registered User
    Join Date
    Aug 2003
    Posts
    127
    es, it is "dangling" reference that return a reference to a local object.
    The copy constructor of Matrix would not be invoked, because you give a move constructor. But the move constructor you defined is not really "move sematics", becuase its members are copy constructed, so you have to use std::move() to transform the members of rhs into rvalue.
    Nana C++ Library is a GUI framework that designed to be C++ style, cross-platform and easy-to-use.

  7. #7
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    i think i'm getting it...

    Code:
    class Foo
    {
    private:
        class Bar
        {
            
        };
        Bar* bar
    public:
        Foo():
            bar(new Bar())
        {
        }
    
        Foo(Foo&& rhs):  
            bar(std::move(rhs.bar))
        {
            rhs.bar = nullptr;
        }
        ~Foo()
        {
            if(bar) delete bar;
        }
    };

  8. #8
    Registered User
    Join Date
    Aug 2003
    Posts
    127
    yes, but it is not necessary using std::move() with bar, because bar is a POD type.
    Nana C++ Library is a GUI framework that designed to be C++ style, cross-platform and easy-to-use.

  9. #9
    Registered User
    Join Date
    Aug 2003
    Posts
    127
    In fact, move constrictor is not a substitute for copy constrcutor. Don't forget copy constrictor if there is a deep copy.
    Nana C++ Library is a GUI framework that designed to be C++ style, cross-platform and easy-to-use.

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    You return locals by value, and if there is a move constructor, this will be invoked to move the result to the caller.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  11. #11
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Quote Originally Posted by anon View Post
    You return locals by value, and if there is a move constructor, this will be invoked to move the result to the caller.
    excellent. thank you. i had inferred this from what compiled, but wasn't sure if that was correct.

    so move constructors will move something off the stack into the heap, or into a scope in the stack?

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    A move constructor is a constructor that takes a reference to a temporary object; nothing more, nothing less.
    Previously we could only use const references to temporary objects.
    Using the new move constructor, the goal is to "steal" the resources from the temp object. Don't forget to properly "remove" the resources from the temporary (like settings pointers to nullptr) to ensure it doesn't destroy them.

    Remember it's still a reference, and you can't return a reference to a local variable!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    thanks everyone. this is proving to be particularly useful for my current purposes - wrapping native matrix code optimized for SIMD / GPGPU for .NET.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Rvalue references and move semantics in C++11
    By webmaster in forum C++ Programming
    Replies: 14
    Last Post: 11-17-2011, 04:01 AM
  2. Returning a rvalue from function
    By Memloop in forum C++ Programming
    Replies: 11
    Last Post: 09-22-2009, 02:47 PM
  3. lvalue rvalue discussion
    By George2 in forum C++ Programming
    Replies: 18
    Last Post: 03-04-2008, 05:48 AM
  4. Get lvalue through rvalue
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 12-17-2007, 08:53 AM
  5. declare references to references works!
    By ManuelH in forum C++ Programming
    Replies: 4
    Last Post: 01-20-2003, 08:14 AM