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
Sebastian Kramer
  • 689
  • 1
  • 9
  • 18

2 Answers2

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 )

P0W
  • 46,614
  • 9
  • 72
  • 119
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)
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055