11.3. Lvalues, rvalues, and referencesΒΆ

In addition to the builtin types and pointers, C++ adds a new type - the reference type. A major addition to C++11 is the addition of the rvalue reference. It is easier to understand rvalue references if we discuss lthe others first.

The original definition of lvalues and rvalues from C is as follows:

In C++, this is still useful as an intuitive view to lvalues and rvalues. However, C++ with its user-defined types introduces some subtleties regarding modifiability and assignability that cause this definition to be incorrect.

An lvalue is an expression that identifies a non-temporary object. For example:

// These are all valid assignments
int i = 42;
i = 43;              // i is an lvalue
int* p = &i;         // i is an lvalue
int& foo();
foo() = 42;          // foo() is an lvalue
int* p1 = &foo();    // foo() is an lvalue

An rvalue is an expression that identifies a temporary object or a literal not assigned a memory address. For example:

// valid assignments
int bar();
int j = 0;
j = bar();     // bar() is an rvalue
j = 42;        // ok, 42 is an rvalue

// invalid
int* p2 = &bar(); // cannot take the address of an rvalue

An rvalue reference is a reference to an rvalue. That is, a reference to a temporary object or a reference to a literal not assigned a memory address. As we will see in the next section, rvalue references are a key component of move operations and forwarding data to another location without copying it.

If X is any type, then X&& is called an rvalue reference to X. To distinguish from ordinary references, the reference X& is now also called an lvalue reference. An rvalue reference is a type that behaves like the ordinary reference X&, but there are several thing to look out for. During function overload resolution, lvalues will prefer function signatures containing lvalue references, and rvalues prefer the new rvalue references:

void foo(X& x);  // lvalue reference overload
void foo(X&& x); // rvalue reference overload

X x;
X foobar();

foo(x); // argument is lvalue: calls foo(X&)
foo(foobar()); // argument is rvalue: calls foo(X&&)

More to Explore

You have attempted of activities on this page