Reputation: 75
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
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
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