Modern C++ In-Depth — Move Semantics, Part 2

Phani Adusumilli
FactSet
Published in
5 min readMay 3, 2022

--

In our last post, we discussed the benefits of using std::move(...) to avoid copying large containers. In this installment, we'll take a look at how we might go about defining move semantics for our own custom types, should we need them.

Terminology

Before we get too deep, let’s examine the terms lvalue and rvalue.

The first letter in these two terms derives from the observation that lvalues typically appear on the left-hand side of an assignment operator, whereas rvalues (when thought of as the temporary return values of function calls) tend to appear on the right-hand side. Since these value categories don’t always appear in the context of assignments, it may be more useful to think of an lvalue as a named object instance whose address can be taken. By extension, rvalues don’t have names and their addresses cannot be taken.

Value References

The magic that makes std::move(...) work is a new type of reference, called an rvalue reference (first introduced in C++11). In order to declare an rvalue reference, use two ampersands instead of one.

Here is an example of this new syntax in comparison to the traditional lvalue reference syntax that we’ve seen before:

Widget& get_widget();
Widget make_widget();
Widget& y = get_widget(); //< An lvalue reference.
Widget&& z = make_widget(); //< An rvalue reference.

--

--

Phani Adusumilli
FactSet
Writer for

I’m an architect who is passionate about distributed systems, APIs, Data Lakes, and Data Mesh in Financial Services