1

I am just starting learning c++. I found an advice on Internet: "Learn with a good book, it is better than videos on youtube." So as I am motivated and I have time I learn with c++ Primer 5th Ed.

In this book, they say: Note: "A reference is not an object. Instead, a reference is just another name for an already existing object."

and: "a reference may be bound only to an object, not to a literal or to the result of a more general expression"

I understand:

int i = 3;
int &ri = i;  // is valid: ri is a new name for i
int &ri2 = 2;  // is not valid: 2 is not an object

Then I don't understand why:

const int &ri3 = 2;  // is valid

They write: "It can be easier to understand complicated pointer or reference declarations if you read them from right to left."

Ok, it is not very complicated. I understand: I declare a variable named ri3, it is a reference (a reference when & is after the type, an address when & is in an expression) to an object of type int and it is a constant.

I think it has already been explained many times but when I search on forums I find complicated (to me) answers to complicated problems, and I still don't understand.

Thank you for your help.

user3019338
  • 75
  • 3
  • 13
  • 1
    `2` is a literal which you can't change. `const` ensures that reference points to a const entity, thus you can't change the object that you refer to by reference. – mic4ael Dec 07 '13 at 15:51
  • `"a reference may be bound only to an object, not to a literal or to the result of a more general expression"` is only true in some cases. – Lightness Races in Orbit Dec 07 '13 at 16:05

2 Answers2

3

https://stackoverflow.com/a/7701261/1508519

You cannot bind a literal to a reference to non-const (because modifying the value of a literal is not an operation that makes sense). You can however bind a literal to a reference to const.

http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/

The "const" is important. The first line is an error and the code won’t compile portably with this reference to non-const, because f() returns a temporary object (i.e., rvalue) and only lvalues can be bound to references to non-const.

For illustrative purposes see this answer.

A non-const reference cannot point to a literal.

The following code will produce an error.

error: invalid initialization of non-const reference of type 'double&' from an rvalue of type 'double'

#include <iostream>

double foo(double & x) {
    x = 1;
}

int main () {
    foo(5.0);
    return 0;
}

Here's Lightness' comment.

[C++11: 5.1.1/1]: [..] A string literal is an lvalue; all other literals are prvalues.

And cppreference (scroll down to rvalue (until C++11) / prvalue (since C++11)):

A prvalue ("pure" rvalue) is an expression that identifies a temporary object (or a subobject thereof) or is a value not associated with any object.

The following expressions are prvalues:

Literal (except string literal), such as 42 or true or nullptr.
Community
  • 1
  • 1
1

It is valid because number literals are actually constants. So the compiler can accept such reference only if it is const.

Matzi
  • 13,770
  • 4
  • 33
  • 50
  • 1
    `const` and "constant" are two different things. Consider `const int r = rand();` – Keith Thompson Dec 07 '13 at 16:16
  • @KeithThompson: Yes, so what? Literals are constants thats why cont references can accept that. I haven't said it's valid in reverse. – Matzi Dec 07 '13 at 16:20
  • 1
    Your conclusion happens to be correct, but it doesn't follow from your premise. It's fairly obvious why `int &ri3 = 2;` (without the `const`) is invalid, but that doesn't imply that `const int &ri3 = 2;` is valid. As I understand it, the compiler has to create an implicit read-only object so that `ri3` can be a reference to it; note that `&ri3` yields a valid address. There must be a special language rule for that. For that matter, there could as easily be a special rule to make `int &ri3 = 2;` valid; it just happens that there isn't. – Keith Thompson Dec 08 '13 at 01:51