One of the most important features in C++0x is one that many users will never use directly: the notion of moving a value from one place to another.

To see why this feature is so important, let's start by creating a string variable and then copying it:

string s = "I am a string!"; string t = s; // Make a copy of s

In order to make t into a copy of s , it is necessary to copy the characters that s contains. The reason, of course, is that the program might change the value of one of these variables, and that change must not affect the value of the other variable. Moreover, the program must allocate memory to contain the copy of s 's characters. Allocating and freeing dynamic memory can be surprisingly slow; it is not unusual for programs to spend more time allocating and deallocating memory than manipulating that memory's contents.

The problem gets worse when we're dealing with containers of strings. For example, calling push_back on a vector<string> may have to copy each string , which in turn must copy each character of each string , together with all the memory allocation and deallocation those copies imply.

In order to see how C++0x has done away with much of this memory manipulation, we're going to start by looking at std::move , which is the part of this feature that usually lives behind the scenes as part of the library. Even if you never use std::move directly, this quick look will help you understand what goes on when you use a part of the library that does use it.

Suppose you knew that the variable s (which we defined earlier) would not be used again after you used it to initialize t . In that case, you wouldn't care what value s had afterward, as long as the value could be destroyed when s went out of scope. In such a case, C++0x enables you to write

string t = std::move(s); // "Steal" state from s

The std::move function simply returns its argument, but with some type magic that we'll describe in the next article. In effect, std::move is a marker that says that you do not intend to look at that argument's value again except to destroy it. Code that uses the result of std::move is permitted to "steal" the value of std::move 's argument. For example, the string library can arrange to steal the resources inside s to use as t 's initial value. This description is intentionally vague; our next article will fill in some more details. For now, there are two points to remember:

Using std::move(s) to initialize t allows t to "steal" s 's value without copying it; after the call to std::move , the value in s may not be used As a result, the program can often avoid the overhead of allocating memory for a duplicate of s , copying s 's characters, and then freeing the memory.

Opportunities to use std::move arise surprisingly often in libraries. For example, to exchange the values of s and t , we might write

{ string temp = std::move(s); s = std::move(t); t = std::move(temp); }

After this code has executed, s and t have each others' former values, and the variable temp has first been given the original value of s , then an indeterminate value; and finally temp has been destroyed.

Of course, this code does what the standard library does with its swap algorithm:

std::swap(s, t);

which is why we say that there is often no need to use this feature directly. In effect, whenever you use std::swap , you're really using std::move .

Other parts of the C++0x library now use std::move too. One important example is as part of increasing the size of a vector . For example, when a vector grows as a result of calling push_back or insert , the C++0x library moves the vector 's elements instead of copying them and then destroying the originals. As a result, when you call push_back on a vector<string> , C++0x avoids having to copy any of the characters in the string s that constitute the vector 's elements. This avoidance can easily make such operations orders of magnitude faster in C++0x than in C++98.

Another case in which the library moves elements rather than copying them is in algorithms such as remove . These algorithms do not change the number of elements of the containers on which they act; instead, they return an iterator that refers to the just past the end of the part of the container that contains the elements we want. For example, we might remove all of the empty strings from a vector<string> named v by writing

// auto was explained in <a href="http://drdobbs.com/cpp/231002092">http://drdobbs.com/cpp/231002092</a> auto it = remove(v.begin(), v.end(), ""); v.erase(it, v.end());

The call to remove moves the nonempty strings (i.e. those not equal to "") to the beginning of v , then returns an iterator that refers to the first element of v (if any) that is not part of the result. The elements between it and v.end() no longer have useful values, so the second line of this example gets rid of them. By moving, rather than copying, the nonempty elements of v to the beginning, the C++0x library allows examples such as this one to run much faster than the C++98 library allows, without the user needing to rewrite any code.