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?
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.