References, lvalues and rvalues
What you'll learn:
- declare a reference as a second name for a variable;
- tell an lvalue from an rvalue, and know what
int&andconst int&bind to; - take the address of a variable and change it through a pointer;
- read the declarations
const int*andint* const.

A computer's memory is like a long street of identical houses. Each variable is a house, and its value lies inside. The variable's name is the nameplate on the door: it is how you find the right house.
A house can carry a second nameplate. The house does not split in two: either nameplate leads you to the same door. In C++, such a second nameplate is called a reference.
You have already met references as function parameters. But a reference can also be declared as an ordinary variable, and then it becomes a second name for another variable:
#include <iostream>
int main() {
int score = 10;
int& ref = score;
ref = ref + 5;
std::cout << score << '\n'; // 15
}Let's go through the example line by line:
int score = 10;builds a house with the nameplatescoreand puts10in it.int& ref = score;hangs a second nameplaterefon the same house. There is no new house and no copy of the value.ref = ref + 5;reads10throughrefand puts15back in the same place.- The program prints
15:refandscoredenote the same place in memory.
A reference initialized with another reference binds to the same variable: after int& alias = ref;, the name alias also denotes score. It is a third nameplate on the same house.
One variable for life
The nameplate is nailed to the house once, when the reference is declared. That is why a reference without an initializer does not compile: int& ref; is an error. The nameplate cannot be moved to another house later either. Assigning through a reference changes the value in the house it is nailed to:
#include <iostream>
int main() {
int first = 10;
int second = 20;
int& ref = first;
ref = second;
std::cout << first << ' ' << second << '\n'; // 20 20
}The line ref = second; does not move the nameplate ref to the house second. It takes the value of second, that is 20, and puts it into the house first. After it, ref still denotes first: if second changes later, neither first nor ref changes. Interviewers like to ask this.
What a reference binds to
An expression that denotes a variable is called an lvalue: for example, score or ref. Such an expression has a house, and a nameplate can be hung on it. The literal 5 or the result of score + 1 is an rvalue: a nameless value stored in no variable. It has no house, so an int& reference does not bind to it.
A const reference, const int&, accepts an rvalue too. For such a value, the compiler builds a temporary object, a nameless variable that holds this value. It binds the reference to that object. Such an object lives as long as the reference:
#include <iostream>
int main() {
int score = 10;
const int& next = score + 1;
score = 50;
std::cout << next << '\n'; // 11
}next denotes a temporary object with the value 11, not score, so changing score does not affect it. For the same reason, a const int& parameter accepts literals and expressions.
This is where the nameplate analogy ends: the temporary object had no house of its own, and the compiler builds one specially for the reference.
Common mistake
A plain reference is bound to the result of an expression:
int main() {
int a = 2;
int b = 3;
int& sum = a + b; // ✗
return sum;
}error: non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'a + b is an rvalue: the sum is not stored in any variable, so an int& cannot bind to it. If sum does not need to change, declare it as const int&. More often, though, an ordinary variable is what you need: int sum = a + b;.
Key points
- A reference is a second name for a variable: both nameplates lead to the same house.
- A reference is bound when it is declared and cannot be re-bound:
ref = second;copies the value. int&binds only to an lvalue, whileconst int&also accepts an rvalue through a temporary object.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.