Non-const reference may only be bound to an lvalue
Asked Answered
B

2

19

Could someone please explain how to simulate this error? and also what this complains about.

"A non-const reference may only be bound to an lvalue" in C++

Britt answered 6/8, 2011 at 15:45 Comment(3)
Which terms don't you understand, 'non-const reference', 'bound' or 'lvalue'?Brenna
@Seth: The question is asking for some code that gives this error. The questioner cannot satisfy your demand.Osbourne
@Steve yes, my eyes missed the word simulate.Ivories
S
53

An lvalue is, roughly, whatever may be on the left side of an assignment statement. References provide aliases for other objects:

std::string s;
std::string & rs = s;  // a non-const reference to s
std::string const & crs = s; // a const reference to s

Given the above definitions, referring to rs or crs is the same as referring to s, except that you cannot modify the referred string through crs, as it is const. A variable is an lvalue, so you are allowed to bind a non const reference to it. In contrast you can bind const references to temporary values as in:

std::string const & crs1 = std::string();

However the following is illegal:

std::string & rs1 = std::string();

This is because using non-const references you imply that you want to modify the referenced object. However temporaries bound to references are destroyed when the reference go out of scope. As it is not always intuitive when C++ creates temporary objects, binding them to non-const references has been disallowed, to avoid you the unpleasant surprise of changing your object as you like, just to see it destroyed a few statements later.

Spectacles answered 6/8, 2011 at 15:57 Comment(6)
@Nicola, one question here. int method1( int & a); Now, does the same apply for thsi one too?Britt
Absolutely. One direct consequence is that you cannot call this function passing an integer literal as argument.Spectacles
@Nicola: Actually, I have always found the restriction quite arbitrary. It is at odds with the fact that you may call a non-const method on a temporary object for example, or that const methods may actually modify mutable attributes...Thoughtout
@Matthieu M.: Well, I can see myself getting fooled once in a while if it was possible to bind temporaries to non const references, but you're right, this situation is inconsistent. Apparently for this reason some standardization committee members wanted to prohibit calling non const member functions on temporaries.Spectacles
@Matthieu: it's not wholly consistent, but I think it makes sense in view of the fact that implicit conversions are applied to function arguments but not to the LHS of a member function call. So, if a non-const reference could be bound then void increment(long &i) { ++i; } would ruin your day then point and laugh if you accidentally put the name of an int variable as the argument. However, if type X converts to type Y, and type Y has a non-const member function increment, there is no equivalent danger of you writing X x; x.increment(); and then wondering why x was unchanged.Osbourne
... so it's "safe" for the language to allow member function calls on temporaries, but "unsafe" to allow temporaries as non-const reference arguments. That said, it's a judgement call in the first place to say that passing a reference to the result of a conversion is (a) unlikely to be what was wanted, and also (b) so bad to be worth the language forbidding it, at the cost of forbidding certain things that do make sense: std::ofstream("filename") << "hello\n" is allowed, but std::ofstream("filename") << Foo(); arbitrarily isn't, since the relevant operator<< must be a non-member.Osbourne
M
10

It means you can't do something like this:

void foo(int &x) { ... }
int bar()        { ... }

foo(bar());

You would need to make foo take a const reference, or assign the result of bar() to a variable, and then pass that into into foo.

Myron answered 6/8, 2011 at 15:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.