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.

# 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 non`const` 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;
clear(temp);
```

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;
```

```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 non`const` 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 non`const` 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.

### More Insights

 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.