user3019338
user3019338

Reputation: 75

"A reference may be bound only to an object", why is "const int &ref = 3;" valid?

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.

Upvotes: 1

Views: 243

Answers (2)

user1508519
user1508519

Reputation:

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.

Upvotes: 3

Matzi
Matzi

Reputation: 13925

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

Upvotes: 1

Related Questions