3

I've written the code posted below. I was hoping to get to move the content of a vector between instances of LargeClass. The move constructor is being used, but instead of moving I get copies only.

Why doesn't the move semantics work as expected here?

Code:

#include <iostream> #include <vector> class LargeClass { public: explicit LargeClass (void): numbers(20, 10) { } LargeClass (const LargeClass &rhs): numbers(rhs.numbers) { std::cout << "Using LargeClass copy constructor" << '\n'; } LargeClass (const LargeClass &&rhs): numbers(std::move(rhs.numbers)) { std::cout << "Using LargeClass move constructor" << '\n'; } const int* getNumbersAddress(void) const { return (numbers.data()); } private: std::vector<int> numbers; }; int main() { LargeClass l1; std::cout << "l1 vector address: " << l1.getNumbersAddress() << '\n'; LargeClass l2(l1); std::cout << "l1 vector address: " << l1.getNumbersAddress() << '\n'; std::cout << "l2 vector address: " << l2.getNumbersAddress() << '\n'; LargeClass l3 = std::move(l2); std::cout << "l1 vector address: " << l1.getNumbersAddress() << '\n'; std::cout << "l2 vector address: " << l2.getNumbersAddress() << '\n'; std::cout << "l3 vector address: " << l3.getNumbersAddress() << '\n'; return 0; } 

Possible output:

l1 vector address: 0x18ce010 Using LargeClass copy constructor l1 vector address: 0x18ce010 l2 vector address: 0x18ce070 Using LargeClass move constructor l1 vector address: 0x18ce010 l2 vector address: 0x18ce070 l3 vector address: 0x18ce0d0 
3
  • It moves the content betwin adresses, but the addresses of containers remain the same no? Commented Jun 30, 2014 at 7:15
  • 3
    The syntax for move constructor should be LargeClass ( LargeClass &&rhs ) Commented Jun 30, 2014 at 7:15
  • 2
    @POW please post this as an answer. What a stupid mistake... Thanks! Commented Jun 30, 2014 at 7:17

2 Answers 2

6

The rvalue references don't make sense in their const forms because you want to modify them (you want to "move" them ). Objects created as const in C++ are in read-only memory, from which grabbing/modifying internal resources won't be possible.

The syntax for move constructor normally should be

  • class_name ( class_name && )

So use :

LargeClass ( LargeClass&& rhs )

Sign up to request clarification or add additional context in comments.

Comments

3

Although a constructor taking const LargeClass&& is technically known as a move constructor (12.8/3) (which is baffling, but explicitly stated in [C++11: 12.8/3]), it's pretty bloomin' useless; it's self-evident that you cannot move from a const expression, because you cannot modify const things and moving implies altering the source! In particular, you cannot actually move from a const vector, which is why that does not occur here and why you see what you see.

A more useful move constructor looks like this:

LargeClass(LargeClass&& rhs) 

3 Comments

Strictly by the book, it is a move constructor. Not a very useful one, but still.
@Angew: True (12.8/3), which is bizarre.
And the move constructor is, in fact, invoked. It just doesn't do what the OP expects.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.