The following code works, so perhaps I am misunderstanding the concept?
Indeed I'm afraid you are misunderstanding the concept. The expression:
j = y;
Does not re-bind j so that it becomes a reference to y: rather, it assigns the value of y to the object referenced by j. Try this after the assignment:
cout << (&j == &x)
And you will see that 1 is printed (meaning j is still an alias for x).
After initialization, a reference becomes an alias for the object it is bound to. Everything you do on the reference, you do it on the object being referenced.
A reference cannot be re-bound or unbound, and it practically becomes just an alternative name for the object it is bound to.