1

I tested c++11 move function, but not become effective. Who can tell me why ? Thanks. The code is as follows:

class Base {
  public:
   Base() { cout << "Base" << endl;}
   ~Base() { cout << "~Base" << endl;}

   Base(const Base& base) { cout << "Copy" << endl; }
   Base& operator=(const Base& base) {cout << "operator=" << endl;}

   Base(Base&& base) { cout << "move" << endl;}
   Base& operator=(Base&& base) { cout << "move=" << endl;}
};

Base b;

Base&& GetResult() {
  return std::move(b);
} 

int main() {
Base&& tmp = GetResult();

cout << &b << endl;
cout << &tmp << endl;

}

Output:

 Base
 0x6013a0
 0x6013a0
 ~Base

Why move copy and move operator= not be called ? And why address is the same ?

Pengcheng
  • 409
  • 1
  • 3
  • 13

3 Answers3

7

To add to the excellent existing answers, I believe the main point of confusion here is what std::move does.

std::move does not move.

It was abysmally named.

It only gives you an xvalue referring to whatever you gave it; this xvalue will bind to a rvalue reference where an lvalue won't. This means the result of std::move can be given to a move constructor or move assignment operator. However, it does not do that for you, and you do not do it here.


Given such strong criticism for the naming, surely you have an alternative suggestion
user2079303

This is a well-trodden topic, but the creator of C++ suggests std::rval, and one of the architects of modern C++ suggests std::rvalue_cast (even though you actually get an xvalue).

Personally, I think std::moveable would have been a nice middle ground.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989
  • Given such strong criticism for the naming, surely you have an alternative suggestion. I would like to hear it, never mind how it's too late to change now. – eerorika Apr 20 '17 at 15:46
  • @user2079303: This is a well-trodden topic, but [the creator of C++ suggests `std::rval()`](http://stackoverflow.com/a/21362110/560648), and [one of the architects of modern C++ suggests `std::rvalue_cast`](http://stackoverflow.com/questions/21358432/why-is-stdmove-named-stdmove#comment32220979_21358433). Personally (and not only because you get an xvalue actually) I think `std::moveable` would have been a nice middle ground. – Lightness Races in Orbit Apr 20 '17 at 15:48
  • Upvote for *It was abysmally named*. Totally agree! PS: you may want to link [this](http://stackoverflow.com/q/3601602/3093378) so OP understands what xvalue/prvalue etc are. – vsoftco Apr 20 '17 at 16:01
  • +1 simply for mentioning movable in the comments; though note that the spelling I gave is both preferred and one character shorter. rvalue_cast is reasonable too. Not a fan of rval. – Nir Friedman Apr 20 '17 at 16:46
  • suggestion: `std::make_moveable` is similar to all the other `std_make_xxx` see: http://en.cppreference.com/mwiki/index.php?title=Special%3ASearch&search=make – Richard Critten Apr 20 '17 at 17:17
  • @RichardCritten: I wrote that originally but it's quite long (hence "middle ground"), plus "make" is being used in a different sense here. – Lightness Races in Orbit Apr 20 '17 at 18:26
  • How about `std::mobilize`? :) movable sounds like it would return true if movable. – eerorika Apr 20 '17 at 21:53
  • @user2079303: Hah, that's not bad (the stdlib tends to use `is_X` for that kind of thing, but point taken) – Lightness Races in Orbit Apr 20 '17 at 21:59
  • 1
    @BoundaryImposition Was discussing this at home and my wife came up with `std::free_to_a_good_home` – Richard Critten May 07 '17 at 19:12
  • @RichardCritten: Hah, sold – Lightness Races in Orbit May 08 '17 at 00:35
3

Why move copy and move operator= not be called ?

I assume that by "move copy" you mean "move constructor". Move assignment operator is not called, because you never use the assignment operator.

There are no moves (nor copies) because Base&& is a reference (an r-value reference to be specific). References refer / point to an object - they do not contain state of the object. When you initialize a reference, no object is copied or moved.

And why address is the same ?

When the address-of operator is applied to a reference, you get the address of the referred object.

eerorika
  • 181,943
  • 10
  • 144
  • 256
2

Let's ignore move semantics for a minute, and only think about familiar, C++98 copy constructors. Given the following code, what output would you expect?

class Base {
  public:
   Base() { cout << "Base" << endl;}
   ~Base() { cout << "~Base" << endl;}

   Base(const Base& base) { cout << "Copy" << endl; }
   Base& operator=(const Base& base) {cout << "operator=" << endl;}
};

Base b;

Base& GetResult() {
  return b;
} 

int main() {
  Base& tmp = GetResult();

  cout << &b << endl;
  cout << &tmp << endl;
}

Of course, you would expect a call to the Base default constructor, followed by the address of b printed twice, followed by the Base destructor. The reason is because you're only constructing one Base instance, and never copying it -- you're only using references.

So it is with your example. You're using rvalue references rather than lvalue references, but the point is the same -- there is only ever one Base variable, and no copying or moving ever happens. If you want to witness move semantics in action, you could try something like this:

Base getBase() {
    return Base{};
}

int main() {
    Base tmp = getBase();
    Base other = std::move(tmp);
}

(The move out of getBase() will probably be optimised out by the compiler, but you should still see the second one.)

Tristan Brindle
  • 15,036
  • 2
  • 31
  • 79