MyVector foo() {
MyVector m(1024, 1204);
// Use vector.
m.move(); // Set bit. Next copy will actual be a move.
return m;
}
Now, I haven't seen his code so I might be wrong, but as I understand it it involves unnecessary run-time state and CPU cycles (the latter will be optimized away though, but not the former).
As I see it it should be possible to do this using the type system instead of run-time state. The idea is to let MyVector::move return a special type that can be converted to a MyVector object, but doing so using move semantics -- not copy semantics. It is used as follows:
MyVector::Move foo() {
MyVector m(1024, 1204);
// Use vector.
return m.move();
}
Here, the result of m.move() is a MyVector::Move object which just holds the state of m needed to reconstruct a MyVector object. Also, MyVector has a constructor that takes MyVector::Move as argument -- this constructor is the move constructor. Here is a complete program showing how it's done. In this program I renamed the move function to operator Move such that the conversion to MyVector::Move is implicit and there is thus no need to call move.
class MyVector {
int* values;
MyVector(MyVector const&); // Don't allow copy.
public:
// Constructor allocates data on heap.
MyVector(int numValues) : values(new int[numValues]) { }
// Destructor deletes.
~MyVector() { delete[] values; }
// Everything is public here for simplicity.
struct Move {
int* values;
Move(int* values) : values(values) { }
operator MyVector() {
return MyVector(*values);
}
};
// Move constructor.
MyVector(Move const& rhs) : values(rhs.values) {
}
// This function was called 'move' in the earlier example.
operator Move() {
Move m(this->values);
this->values = 0;
return m;
}
// Access the contents of the vector.
int& operator[](int idx) {
return values[idx];
}
};
MyVector::Move get() {
MyVector h(1024);
h[10] = 20;
return h;
}
int main() {
MyVector h(get());
return h[10];
}
I must say that I'm surprised that this pattern hasn't popped up earlier for me. Granted, it has it's share of noise, but it does what it promises: moves without the unnecessary new and delete[].