13

The function std::move() is defined as

template<typename T>
typename std::remove_reference<T>::type&& move(T && t)
{ 
    return static_cast<typename std::remove_reference<T>::type&&>( t ); 
}

There are four places where I can imagine the move constructor to be called:

  1. When the parameter is passed.
  2. When the cast is performed.
  3. When the result is returned.
  4. Not in the std::move() function itself but possibly at the place where the returned reference ultimately arrives.

I would bet for number 4, but I'm not 100% sure, so please explain your answer.

Toby Speight
  • 23,550
  • 47
  • 57
  • 84
Ralph Tandetzky
  • 20,730
  • 9
  • 61
  • 117

2 Answers2

8

There is no move construction going on. std::move() accepts a reference and returns a reference. std::move() is basically just a cast.

Your guess 4. is the right one (assuming that you are actually calling a move constructor in the end).

Ali
  • 51,545
  • 25
  • 157
  • 246
  • 3
    `std::move` is such a silly name because _it doesn't move anything_ (i.e. because, yes, the answer is `4`). I've had this argument with committee members and they are of the opinion that it's fine because "people will only ever use `std::move` as a precursor to moving something". I feel that this completely violates the _spirit_ of C++. – Lightness Races in Orbit Feb 07 '13 at 12:26
  • @LightnessRacesinOrbit Yes, I find the name `move` confusing too. – Ali Feb 07 '13 at 12:38
  • It should have been called `to_movable` or `make_movable`. I guess that is a little too much typing for people using IDE's without auto-completion. – usr Feb 06 '14 at 16:47
  • @usr [Why is `std::move` named `std::move`?](http://stackoverflow.com/q/21358432/341970) – Ali Feb 06 '14 at 16:56
  • @Ali interesting history lesson. Still, `make_movable` is consistent with the main point of that post (and not plain wrong like `move` is. It is undeniably wrong. It does not describe what the method does. It describes something it *doesn't* do.). – usr Feb 06 '14 at 17:02
  • @usr Yes, I agree. I just wanted to let you know that there is an explanation from someone on the C++ standardization committee. – Ali Feb 06 '14 at 17:36
3

std::move is just a type cast, it tells the compiler that the type is an rvalue.

ArtemGr
  • 9,567
  • 2
  • 44
  • 75
  • 2
    That's kinda what I though. Hence `std::move()` actually doesn't move and doesn't even need to lead to a move operation. – Ralph Tandetzky Feb 07 '13 at 11:44
  • That's why I don't understand some people saying that the move can prevent the (N)RVO. From my experiments with GCC the (N)RVO works just fine with move. – ArtemGr Feb 07 '13 at 11:51
  • 1
    Using `return std::move(local_var);` instead of just `return local_var;` will indeed inhibit (N)RVO, see [this](http://stackoverflow.com/a/12288328/500104). – Xeo Feb 07 '13 at 12:18
  • @Xeo, I saw this answer but I think it's logic is wrong. Move can convert NRVO into RVO, it doesn't inhibit the optimization per se. Do you have an example when move inhibits RVO, so that I can test it? – ArtemGr Feb 07 '13 at 12:22
  • 1
    It does inhibit (N)RVO, simply because the standard says (N)RVO is **only** allowed to happen when you write `return local_var;`. – Xeo Feb 07 '13 at 12:24
  • @Xeo, aren't you confusing NRVO and RVO? You don't need a name for the RVO, and NRVO is an extension of RVO. You can't perform NRVO on rvalue, but you can still perform the optimization (the RVO). – ArtemGr Feb 07 '13 at 12:26
  • @ArtemGr if you can observe the difference, `return std::move(local_var);` cannot optimize the move away. If the difference is not observable, the question is, as always, made moot by the as-if rule. – R. Martinho Fernandes Feb 07 '13 at 12:31
  • @R. Martinho Fernandes, there is no difference with GCC. – ArtemGr Feb 07 '13 at 12:31
  • Try with a move constructor that causes observable effects, like `std::cout << "Hey, I'm moving"`. – R. Martinho Fernandes Feb 07 '13 at 12:32
  • 2
    @ArtemGr Try with a more conformant version http://stacked-crooked.com/view?id=d4bb782e20433f48f9a61cc2106d502d – R. Martinho Fernandes Feb 07 '13 at 12:36