Learn how to emulate C++11 move semantics in C++03 compilers using Boost.Move.
Move Semantic has been introduced in C++11 to solve a very annoying issue: avoid the unnecessary copy of temporary objects. To understand better what I am saying, take a quick look at these few lines below:
This chunk of code looks pretty easy. There is the declaration of a new type Foo that is simply a shortname for a vector of generic type T, a factory method named getFoo() that return a Foo object, and a local variable vec.
Now, let me ask you a question: how many Foo objects have been created?
The answer is 3. Below the explaination:
an object is created inside the getFoo() function
a temporary object is created to store the object returned by getFoo()
the third object is simple the local variable vec
If the cost payed to create and destroy a temporary objects Foo is expensive, we could have a noticeable impact on the performance. Generally, if a function returns a very expensive object, it could be nice to assign the return value directly to a our local variable, without the use of unnecessary and expensive temporary objects. The issue here is that we have no countrol over temporary object. Temporary variables don’t appear in the source code and we cannot see them because they are inserted automatically by the compiler in some circustamces (e.g. when functions return objects).
If you are using a compiler which supports C++11, the use of Move Semantics is the natural way to solve this kind of issues. This feature is fundamentally based on a simple idea: is allowed to modify temporary objects stealing resources from them. In other words, move is a potentially destructive copy. Technically speaking, the mechanism is implemented thanks to rvalue reverences (rref), which are used to identify a moveable object. You can get more details about this tecnique reading What the code say.
In C++03 there are not nor rref nor move semantics. Fortunally, with Boost.Move library is still possible to write some portable code that emulates move semantics.
To use this feature, just add #include <boost/move/move.hpp> to your program. Then, follow 4 steps:
Put the following macro in the private section: BOOST_COPYABLE_AND_MOVABLE(classname)
Leave copy constructor as is.
Write a copy assignment taking the parameter as BOOST_COPY_ASSIGN_REF(classname)
Write a move constructor and a move assignment taking the parameter as BOOST_RV_REF(classname)
The Boost.Move library is implemented in a very efficient way. All functions never copy passed values, nor call any dynamic memory allocations or virtual functions. Moreover, if a C++11 compiler is used, all the macros for rvalues emulation are expanded to C++11-specific features, while on C++03 compilers rvalues are emulated using specific datatypes.
Boost C++ Application Development Cookbook, by Antony Polukhin