Moving semantics of right-value reference and right-value reference Semantics
This article is translated from a classic article about the reference and interpretation of the right value. If you can still use English, go to the original English text. Thbecker.net/articles/rvalue_references/section_01.html
The reference to the right value is a feature in c ++ and has already entered the c ++ 11 standard. It may be hard to understand when you get started with it, but he is indeed a very useful thing.
The right value reference solves two problems:
1. move semantics 2. Perfect forwarding.
Next, we will briefly introduce the move semantics. Before introducing the move semantics, we need to first introduce the meaning of the left and right values.
In C language, we define the left value as an expression e, which can appear either on the left or on the right of the value assignment operator. The right value is: only the expression that appears on the right of the value assignment operator.
Int a = 42; int B = 43; // all values of a B are left a = B; // okb = a; // oka = a * B; // OK // a * B is the right value int c = a * B; // OK, the right value appears in = a * B = 42; // error, the right value cannot appear on the left
In c ++, the left and right values are almost the same, but there is a slight change. In c ++, the left value is: The expression for which you can take the address (&) operation, and the right value is a non-left value.
// Left value: // int I = 42; I = 43; // OK, I is the left value int * p = & I; // OK, I is the left value int & foo (); foo () = 42; // OK, foo () is the left value int * p1 = & foo (); // OK, foo () is the left value // the right value: // int foobar (); int j = 0; j = foobar (); // OK, foobar () is the right value int * p2 = & foobar (); // error, cannot take the right value expression address j = 42; // OK, 42 is the right value
Suppose we have a class X, which has a member function as a pointer and may point to some resources. The corresponding construction, destructor, and copy operations require some special processing work.
For example, if we use std: vector, the copy operation of X is similar to the following:
X & X: operator = (X const & rhs) {// [...] // first reclaim the resource m_pResource // copy the resource m_pResource pointed to by rhs // then point m_pResource to the new memory location. // [...]}
Or you may encounter the following code:
X foo();X x;x = foo();
Then the third sentence, that is, the last sentence, needs to execute three operations:
1. Release the original x resource.
2. Clone the resource in the return value of foo to the resource x.
3. Destroy the resources in the returned value.
Obviously, this is very inefficient. The smarter way is to perform swap operations, switch the resources of x and return value x, and then the resources of the original x will be automatically released.
In other words, what we want to do is:
...
swap(m_pResource,rhs.m_pResource);
...
This is called the move semantics. In c ++ 11, this feature can be implemented through overloading:
X& X::operator=(<???> rhs){ // [...] // swap(m_pResource,rhs.m_pResource); // [...] }
So this ??? What type is it? Of course, it should be a reference type to reduce unnecessary copy of values, and then we want to separate it from the traditional reference type, because we want to call ??? This overload, and when the right operand is the left value, the original reference value assignment structure is called, so okay, then we will take ??? It is called "right value reference.