views:

128

answers:

5

What is the difference between:

const double& pi = 3.14;

and (no ampersand):

const double pi = 3.14;

They both seem to have the same L and R values so what is the difference? Thanks.

A: 

const double& is a reference to a constant double, the other one is a constant double. A reference is kind of a const pointer, a pointer that never changes.

dutt
tree-hacker
Regarding performance passing by value is really expensive when passing big objects, that's why you want reference. Regarding const int there's no real reason to use references when passing to functions, sometimes int is smaller. Functionally a reference isn't an actual int, it's a reference to another int. But you can use them similarly.
dutt
A: 

The reference isnt const only the value is const, so you should be able reassign referense, that means the following would be ok:

const double& pi = 3.14;
const double  pi2 = 2.78;
pi = *(&pi2);
Adesit
Mm, nope. References cannot be reseated. This tries to assign a value to a const variable, and is ill-formed.
GMan
maybe like this:pi = *( ?
Adesit
GMan
i dont want assign a variable but reassign a ref. Well i admit, its just a fast guess. I didnt compile.
Adesit
You can't "reassign" a reference. It is inherently constant. Once "assigned" it can never be "reassigned". Also, there is no point to taking the address of `pi2` and then dereferencing it. I'm not even sure you can initialize a reference to a literal, as the literal is not a variable.
Sion Sheevok
@Adesit: Like I've said twice, you cannot reseat a reference. @Sion: It creates a temporary and binds to it.
GMan
+8  A: 

For your particular example there's no difference.

And that means, no way to tell them apart, whatsoever.

However, since the first binds a reference to a temporary, when the type is of class type the temporary can be of a derived class, e.g. produced by a function! And it then has its destructor properly called at the end of the scope. This little el neato trick is used in ScopeGuard implementations (see the original ScopeGuard article in DDJ, by Petru Marginean and Andrei Alexandrescu -- Petru invented ScopeGuard and Andrei made a more general thing on top).

I once asked Bjarne Stroustrup, who created the C++ language, why the syntax in your first declaration is supported.

And his reply was that it was mostly to have uniform rules (i.e. to not make any special exception for local references as opposed to references as formal parameters). I think at that time neither of us were familiar with ScopeGuard. It's simple in retrospect, but it takes a mind like Petru's, or Andrei's, to come up with something like that! :-)

Cheers & hth.

Alf P. Steinbach
Great answer. Just wanted to ask, in what sense is the first one "temporary", as in what exactly does this mean? How is it different to the second? Thanks.
tree-hacker
A reference is just a reference to something else. You can think it as just an alias. But internally the compiler can implement it as a pointer, like, you write `int const int const* const x = `. Or, it might optimize the whole thing away... But the formal rule for binding a reference to an rvalue is that a temporary is created, and the reference is set to refer to that temporary. The rules for the more general case differ a little between C++98 and C++0x, but roughly, that's it.
Alf P. Steinbach
OK great, thanks,
tree-hacker
"And that means, no way to tell them apart, whatsoever.", don't forget C++0x' decltype, and that a const reference isn't an integral constant expression. I dunno a way to get a valid C++03 program to print "ref" or "nonref", given the above two variables and applied to the one or the other, though. C++0x wasn't asked about, but I thought I would just throw it in.
Johannes Schaub - litb
Alf P. Steinbach
+1  A: 

The important difference with a reference is that a reference itself is inheritly constant. Once the reference itself has been initially assigned to a variable, it can not then reference another variable. All attempts to modify it will modify the variable it refers to. Given this, the const will mean that the reference is a reference to a const int.

const int A;
const int B;
const int& Reference = A;
Reference = B; // Error, the value of A can not be assigned, nor would this *ever* be able to make Reference refer to B.

You can also test this theory about a reference itself being constant like so:

const int& const Reference; // Should give a warning about the second const being redundant.
Sion Sheevok
+1  A: 

A bit of clarification about constant references, references and constants for doubles.

Reference

A reference refers to an existing an object and cannot be reseated. That is, once you declare (define) the reference, it will always refer to that item.

Constant Reference

The C++ language allows for declaring of a constant reference. This tells the compiler that the reference will not change. This may be redundant since references cannot be reseated. However, the language syntax allows it.

Constant

A constant is a value, and does not refer to anything.

Optimizations & Substitutions

The compiler is allowed to substitute (replace) a reference to an object, constant or literal with the corresponding object, constant or literal, provided that the compiler can guarantee that no write operations are performed to that object within the scope it is used in. This determination may become difficult when the reference is passed to methods or functions within that scope.

Specifying the const modifier to a reference will make the compiler's job easier for optimizing. The constant reference is a contract with the programmer and user that the reference will not be changed.

Thomas Matthews
tree-hacker