Re: move, instead of copy, assignment
Hi!
Jonathan Lee wrote:
I was wondering if there is a good way to detect an assignment from
an anonymous variable, so that the assignment might be accomplished by
a move, instead of a copy. For example:
MatrixClass x, y, z
// stuff happens to x, y, and z
// ...
z = x + y;
You might think about reference type semantics for such complex objects.
I.e. different MatrixClass instances might refer to the same storage.
Firstly you could make the objects immutable. This is useful if
reassignments or changes typically require reallocation anyway.
(example: strings). If the objects are immutable you do not have to take
care of unexpected value changes because of the references.
But if the dimensions of your MatrixClass are likely not to change but
only the values change then immutable objects will cause far too many
reallocations. In this case you could use copy on write semantics. That
means that the matrix class firstly checks whether the reference counter
is 1, i.e. the storage is already private before it makes any changes to
the storage. Otherwise the assignment (or change) is made to new storage.
The disadvantage of the reference counting is that you typically have to
deal with threading issues. If normal thread safety satisfy your needs
(I.e. no threads copies MatrixClass instances that can asynchronously
change without a mutex. - I guess that is OK.), then a lock free
implementations is your choice. boost::intrusive_ptr should satisfy your
needs for the holder of the matrix storage.
Suppose MatrixClass keeps a pointer to its data, which will be deleted
on destruction. Rather than copy (x + y) to z, it would be cheaper to
simply exchange the pointers inside the classes and allow the old z
data be deleted when (x + y) is destroyed.
This is a common way, but it requires changes to the application code
rather then only changes to the library.
Also, if you want to benefit from in-place operations changes to the
application code are required. Example: assuming that not only x+y but
also x and y are temporary values you could write:
z.swap(x) += y;
which obviously does not require any additional allocation. But, the
readability is limited.
Another idea could use a proxy type for the rvalues of operator which
behaves different on assignment and copy construction. I don't know
about C++0x but the move semantics mentioned sounds similar.
Marcel