Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Channels ▼

Andrew Koenig

Dr. Dobb's Bloggers

Two Kinds of References

August 31, 2011

This post provides some of the background behind one of C++'s odder rules, namely the one that requires a nonconst reference to be attached to an lvalue. This rule evolved over several years, and understanding it is a useful prelude to understanding how rvalue references work.

The idea behind a C++ reference is simple — at least in theory. A reference is nothing more than another name for an object. For example:

int a;
 int& b = a;

We have defined b as a reference and initialized it from a, which means that b is just another name for a. Once we have defined a and b in this way, reading or writing the value of a has the same effect as reading or writing the value of b, and vice versa.

The most common use of references is as function parameters:

           void clear(int& n) { n = 0; }

Here we have defined a function named clear that sets its argument to zero, so that if we call clear(a), with a defined as we did earlier, the effect is to set a to zero. Calling clear(b) has the same effect, because b is just another name for a.

What happens if we call clear with something other than a variable, such as clear(42) or clear(a+1)? It makes no sense to set 42 to zero, and although it would be possible to make a+1 zero by setting a to -1, it would be impossible for such a technique to work in general.

So the question arises: What should happen if a reference is initialized from something that is not a variable? Once upon a time, C++ answered this question by saying that the argument should be copied and the reference attached to the copy. In other words, the effect of clear(a+1) was similar to

int temp = a+1;

This treatment allowed programmers to use references as a way for functions to avoid having to copy their arguments. For example, by writing

bool greater(string& s1, string& s2) { return s1 > s2; }

we could avoid having to copy s1 and s2 merely in order to compare them. In other words, from the start, references solved two distinct problems. Programmers sometimes wanted to avoid copying an argument in order to ensure that changes to the reference would be reflected in the argument; other times they wanted to avoid copying it for versions of runtime speed alone.

At some point, someone wrote a statement like

cin >> x + y;

by mistake instead of writing

cout << x + y;

and was surprised that it quietly compiled. Obviously, input and output are fine examples of the two different ways in which one might want to use references: One passes a variable as the second argument to >> because one intends to read into it, but << takes a reference merely for speed reasons.

After much discussion, the fledgling C++ community realized that these two uses were different, and, after much more discussion, decided to use const to distinguish between them. The idea is that when you bind a reference to a const object, it is obvious that you do not intend to use the reference to change the object — it's const, so you can't do it. If, on the other hand, you bind a reference to a nonconst object, then you're saying that you intend to use the reference to change the object. In that case, the compiler will require the object to be an lvalue:

           int a;
           int& b = a;                        // OK
           int& c = 42;                      // Not OK — 42 is not an lvalue and c is not const
          const int& d = 42;                // OK

The definition of d is permitted because the const is a promise that d will not be used to change the value of 42. Therefore, the compiler is permitted to copy 42 and attach d to the copy without having to worry that the programmer will be surprised after an attempt to change d.

The idea that references serve two different purposes persisted for many years. However, C++11 reflects a third use for references, which complements the first two:

  • A reference to nonconst must refer to the original object so that changes to the reference will be reflected as changes to the object.

  • A reference to const may refer to a copy of the object because the reference will not be used to change the object.

  • An rvalue reference may refer to the original object — even though the reference might be used to change the object — because the original object's value is no longer important.

In effect, an rvalue reference is how a programmer tells the compiler that an object is about to be discarded or reused, so that its current value can be recycled.

We'll see next week how such instructions to the compiler can be useful.

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.