Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Am I the only one who finds std::move a little too difficult to understand?

So I have been reading about std::move, std::forward, rvalues, lvalues ad so on in SO and other places. But I find that I can't grasp it. Even though I sometimes get into fixes, I think I understand basic stuff about pointers, references, etc which were in C++ before all this. Is it me or are these stuff getting too heavy?

like image 825
nakiya Avatar asked Nov 12 '10 02:11

nakiya


2 Answers

I would recommend reading the original proposal if you haven't already:

A Proposal to Add Move Semantics Support to the C++ Language

It lays out very clearly the problems that can be solved with rvalue references and move semantics and how rvalue references and move semantics can be used to solve those problems.

Standards committee papers are often dense and difficult to understand, but this one is quite accessible and very much worth reading. The rvalue references and move semantics as specified in the final C++0x standard (whenever that happens) may be different from what is proposed in this paper, but the concepts are still the same.

like image 113
James McNellis Avatar answered Nov 01 '22 02:11

James McNellis


Your question is very general. Maybe I can get you started:

  • Ignore the functions std:move() and std::forward() at the beginning
  • One aspect of RValue References is to save temporaries.
    • In C++03 code, count the temps for Matrix z = a + b + c + d; (with Matrix a,b,c,d;)
    • implement yourself operator+ on Matrix with overloaded RValue References.
    • you should be able to reduce the number of temporaries greatly.

If you want to see a simple use of std::move(): Help the compiler to avoid introducing a copy for a return value:

  • Make a container class like Image -- costly to copy.
  • Do not forget to implement the move and copy-assign
  • invent a factory function that works like this:

    Image load_matching_size(const char *fn_small, const char *fn_big) {
       pair<Image> ii = load_2_images(fn_small, fn_big);
       return ii.first.width() >= 64 ? ii.first : ii.second;
    }
    
  • Can you count the numbers of temporaries? Note that the return will need an additional one and copy! (The example is designed so that return-value-optimization ("RVO") should not be possible)

  • Can you see that this would not be necessary? The Images in ii will be thrown away shorty after the function returned. Could the compiler use then for the return value? (No it could not. RVO would work if we had only one Image).
  • With move in the return you can tell the compiler, that you do not need ii further and that it can use it for the return. And thus spare a costly copy my using the move-c'tor instead of the copy-c'tor for the return.
like image 40
towi Avatar answered Nov 01 '22 03:11

towi