tags:

views:

308

answers:

5

Possible Duplicate:
Why are references not reseatable in C++

I am trying to more or less swap two reference variables (as practice, I could have swapped the actual variables). I tried doing this by making a temporary variable and making one of the references equal the other, but this got shot down by the compiler. Here is an example:

void Foo()
{
   //code
   int& ref1 = a;
   int& ref2 = b;
   int temp;

   temp = ref1;
   ref1 = ref2;
   ref2 = temp;

   //or, better yet
   std::swap(ref1, ref2);
}

I got an error, and looked on the faq lite. It details that they cannot be reseated, but does not explain why. Why?

Here is a link to the Faq Lite for reference (<---, get it?).

+5  A: 

A reference is an alias to object.
Alias can not be changed (we are not spies ;-)

Martin York
+7  A: 

Because there is no syntax to do it:

int x = 0;
int y = 1;
int & r = x;

Now if I say:

r = y;

I assign the value of y to x. If I wanted to reseat I would need some special syntax:

r @= y;    // maybe?

As the main reason for using references is as parameters and return types of functions, where this is not an issue, it didn't seem to C++'s designers that this was a path worth going down.

anon
Oh, I never considered what exactly the assignment operator was doing in this instance. So r = y would just set x to 1?
Hooked
Yes indeedy.
anon
+2  A: 

Because references don't have an address of their own (if they do that is implementation dependent, and you can't access them with the & operator directly).

The & operator is used to get the address of the thing that the reference is referring to.

Whereas a pointer does have an address of its own and you can access it with the & operator.

int x = 4;
int *p = &x;
//p holds the address of x
//&p holds the address of p.

int &r = x;
//&r holds the address of x

And if something doesn't have an address of its own then it can't store a value inside of it. And if it can't store a value inside of it, then it can't be changed.

I think the parashift C++ FAQ on references says it best:

Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object. It is not a pointer to the object, nor a copy of the object. It is the object.

and again in FAQ 8.5 :

Unlike a pointer, once a reference is bound to an object, it can not be "reseated" to another object. The reference itself isn't an object (it has no identity; taking the address of a reference gives you the address of the referent; remember: the reference is its referent).

Brian R. Bondy
+1  A: 

Look at your code again:

temp = ref1;
ref2 = temp;
ref1 = ref2;

References are aliases. All operations that you do on the reference are performed on the object it references. In your code above, how should the compiler magically know that you aren't trying to assign the values to referenced variables, but are rather trying to change the reference itself? There's no syntax to indicate the difference between that, and, for example:

ref1 = 3;

which you'd normally expect to assign a value 3 to the object referenced by ref1.

In short, this is simply by design. If you want "reseatable" references, then you just use pointers (or, if you want to avoid accidential pointer arithmetic, boost::optional).

Pavel Minaev
A: 

Unlike pointers, references are designed to guarantee that they always refer to an object. To meet this gaurantee, the compiler requires that all references be initialized in their declaration and disallows you from reassigning them.

Similar to pointers, reference variables allow you to access the same instance of an object through multiple locations - but unlike pointers, reference provide a greater level of safety.

LBushkin