Constant references

A const reference is a reference that may refer to a const object:

Example

#include <iostream>

int main() {
	const int ival = 1024;
	const int &refVal = ival; // ok: both reference and object are const
	int &ref2 = ival; //error: non const reference to a const object

	getchar();
	return 0;
}

We can read from but not write to refVal. Thus, any assignment to refVal is illegal. This restriction should make sense: We cannot assign directly to ival and so it should not be possible to use refVal to change ival.
 
For the same reason, the initialization of ref2 by ival is an error: ref2 is a plain, nonconst reference and so could be used to change the value of the object to which ref2 refers. Assigning to ival through ref2 would result in changing the value of a const object. To prevent such changes, it is illegal to bind a plain reference to a const object.
 
A const reference can be initialized to an object of a different type or to an rvalue (Section 2.3.1, p. 45), such as a literal constant:

Example

#include <iostream>

int main() {
	int i = 42;
	//  legal for const references only
	const int &r = 42;
	const int &r2 = r + i;
	
	std::cout<<r;
	std::cout<<"\n"<<r2;

	getchar();
	return 0;
}

The same initializations are not legal for nonconst references. Rather, they result in compile-time errors. The reason is subtle and warrants an explanation.
 
This behavior is easiest to understand when we look at what happens when we bind a reference to an object of a different type. If we write.

double dval = 3.14;
const int &ri = dval;

the compiler transforms this code into something like this:

int temp = dval;          // create temporary int from the double
const int &ri = temp;   // bind ri to that temporary

If ri were not const, then we could assign a new value to ri. Doing so would not change dval but would instead change temp. To the programmer expecting that assignments to ri would change dval, it would appear that the change did not work. Allowing only const references to be bound to values requiring temporaries avoids the problem entirely because a const reference is read-only.