As promised, more content from the newly completed Implementing QuantLib. This week, a class with its feet firmly planted in the past.
In other news, there are still places available for my next course. Click the link, I’ll wait.
Done? Great. Here we go.
Follow me on Twitter if you want to be notified of new posts, or subscribe via RSS or email: the buttons for that are in the footer. Also, I’m available for on-site training in Europe and UK: visit my Training page for more information.
Disposable class template was an attempt to implement move
semantics in C++98 code. To give credit where it’s due, we took the
idea and technique from an article by Andrei Alexandrescu  in which
he described how to avoid copies when returning temporaries.
The basic idea is the one that was starting to float around in those
years and that was given its final form in C++11: when passing a
temporary object, copying it into another one is often less efficient
than swapping its contents with those of the target. You want to move
a temporary vector? Copy into the new object the pointer to its
storage, instead of allocating a new one and copying the elements. In
modern C++, the language itself supports move semantics with the
concept of rvalue reference ; the compiler knows when it’s dealing
with a temporary, and we can use
std::move in the few cases when we
want to turn an object into one. In our implementation, shown in the
following listing, we don’t have such support; you’ll see the
consequences of this in a minute.
The class itself is not much to look at. It relies on the template
argument implementing a
swap method; this is where any resource
contained inside the class are swapped (hopefully in a cheap way)
instead of copied. The constructors and the assignment operator all
use this to move stuff around without copies—with a difference,
depending on what is passed. When building a
another one, we take it by
const reference because we want the
argument to bind to temporaries; that’s what most disposables will be.
This forces us to use a
const_cast in the body, when it’s time
swap and take the resources from the disposable. When
Disposable from a non-disposable object, instead, we
take is as a non-
const reference; this is to prevent ourselves
from triggering unwanted destructive conversions and from finding
ourselves with the empty husk of an object when we thought to have a
usable one. This, however, has a disadvantage; I’ll get to it in a
The next listing shows how to retrofit
Disposable to a
Array, in this case.
As you see, we need to add a
constructor and an assignment operator taking a
C++11, they would be a move constructor and a move assignment
operators taking an rvalue reference) as well as the
method that will be used in all of them. Again, the constructors take
const reference and cast it later, in
order to bind to temporaries—although now that I think of it, they
could take it by copy, adding another cheap swap.
Finally, the way
Disposable is used is by returning it from
function, like in the following code:
Returning the array causes it to be converted to
and assigning the returned object causes its contents to be swapped
Now, you might remember that I talked about a disadvantage when I
showed you the
Disposable constructor being safe and taking an
object by non-
const reference. It’s that it can’t bind to
temporaries; therefore, the function above can’t be written more
because that wouldn’t compile. This forces us to take the more
verbose route and give the array a name. (Well, it doesn’t actually
force us, but writing
return Disposable<Array>(Array(n, 10)) is
even uglier than the alternative.)
Nowadays, of course, we’d use rvalue references and move constructors
and forget all about the above. To tell the truth, I’ve a nagging
Disposable might be getting in the way of the
compiler and doing more harm than good. Do you know the best way to
write code like the above and avoid abstraction penalty in modern
C++? It’s this one:
In C++17, the copies that might have been done when returning the
array and when assigning it are guaranteed to be elided (that is, the
compiler will generate code that builds the returned array directly
inside the one we’re assigning); most recent compilers have been doing
that for a while, without waiting for the standard to bind them. It’s
called RVO, for Return Value Optimization, and using
Disposable prevents it and thus might make the code slower
instead of faster.
 A. Alexandrescu, Move Constructors. In C/C++ Users Journal, February 2003.
 H.E. Hinnant, B. Stroustrup and B. Kozicki, A Brief Introduction to Rvalue References. C++ Standards Committee Paper N2027, 2006.