Using rvalue references (C++11)
In C++11, you can overload functions based on the value categories of arguments and similarly have lvalueness detected by template argument deduction. You can also have an rvalue bound to an rvalue reference and modify the rvalue through the reference. This enables a programming technique with which you can reuse the resources of expiring objects and therefore improve the performance of your libraries, especially if you use generic code with class types, for example, template data structures. Additionally, the value category can be considered when writing a forwarding function.
Move semantics
When you want to optimize the use of temporary values, you can use a move operation in what is known as destructive copying. Consider the following string concatenation and assignment:
std::string a, b, c;
c = a + b;
In this program, the compiler first stores the result of a + b in an internal
temporary variable, that is, an rvalue.
string& operator = (const string&)With this copy assignment
operator, the assignment consists of the following steps:- Copy the temporary variable into
cusing a deep-copy operation. - Discard the temporary variable.
c is not efficient because the
temporary variable is discarded at the next step.To avoid the needless duplication of the temporary variable, you can implement an assignment
operator that moves the variable instead of copying the variable. That is, the argument of the
operator is modified by the operation. A move operation is faster because it is done through pointer
manipulation, but it requires a reference through which the source variable can be manipulated.
However, a + b is a temporary value, which is not easily differentiated from a
const-qualified value in C++ before C++11 for the purposes of overload resolution.
string& operator= (string&&)With this
move assignment operator, the memory allocated for the underlying C-style string in the result of
a + b is assigned to c. Therefore, it is not necessary to allocate
new memory to hold the underlying string in c and to copy the contents to the new
memory.string move assignment
operator:string& string::operator=(string&& str)
{
// The named rvalue reference str acts like an lvalue
std::swap(_capacity, str._capacity);
std::swap(_length, str._length);
// char* _str points to a character array and is a
// member variable of the string class
std::swap(_str, str._str);
return *this;
}However,
in this implementation, the memory originally held by the string being assigned to is not freed
until str is destroyed. The following implementation that uses a local variable is
more memory
efficient:string& string::operator=(string&& parm_str)
{
// The named rvalue reference parm_str acts like an lvalue
string sink_str;
std::swap(sink_str, parm_str);
std::swap(*this, sink_str);
return *this;
}