lvalue to rvalue implicit conversion

Viewed 19841

I see the term "lvalue-to-rvalue conversion" used in many places throughout the C++ standard. This kind of conversion is often done implicitly, as far as I can tell.

One unexpected (to me) feature of the phrasing from the standard is that they decide to treat lvalue-to-rvalue as a conversion. What if they had said that a glvalue is always acceptable instead of a prvalue. Would that phrase actually have a different meaning? For example, we read that lvalues and xvalues are examples of glvalues. We don't read that lvalues and xvalues are convertible to glvalues. Is there a difference in meaning?

Before my first encounter with this terminology, I used to model lvalues and rvalues mentally more or less as follows: "lvalues are always able to act as rvalues, but in addition can appear on the left side of an =, and to the right of an &".

This, to me, is the intuitive behavior that if I have a variable name, then I can put that name everywhere where I would have put a literal. This model seems consistent with lvalue-to-rvalue implicit conversions terminology used in the standard, as long as this implicit conversion is guaranteed to happen.

But, because they use this terminology, I started wondering whether the implicit lvalue-to-rvalue conversion may fail to happen in some cases. That is, maybe my mental model is wrong here. Here is a relevant part of the standard: (thanks to the commenters).

Whenever a glvalue appears in a context where a prvalue is expected, the glvalue is converted to a prvalue; see 4.1, 4.2, and 4.3. [Note: An attempt to bind an rvalue reference to an lvalue is not such a context; see 8.5.3 .—end note]

I understand what they describe in the note is the following:

int x = 1;
int && y = x; //in this declaration context, x won't bind to y.
// but the literal 1 would have bound, so this is one context where the implicit 
// lvalue to rvalue conversion did not happen.  
// The expression on right is an lvalue. if it had been a prvalue, it would have bound.
// Therefore, the lvalue to prvalue conversion did not happen (which is good). 

So, my question is (are):

1) Could someone clarify the contexts where this conversion can happen implicitly? Specifically, other than the context of binding to an rvalue reference, are there any other where lvalue-to-rvalue conversions fail to happen implicitly?

2) Also, the parenthetical [Note:...] in the clause makes it seem that we could have figured it out from the sentence before. Which part of the standard would that be?

3) Does that mean that rvalue-reference binding is not a context where we expect a prvalue expression (on the right)?

4) Like other conversions, does the glvalue-to-prvalue conversion involve work at runtime that would allow me to observe it?

My aim here is not to ask if it is desirable to allow such a conversion. I'm trying to learn to explain to myself the behavior of this code using the standard as starting point.

A good answer would go through the quote I placed above and explain (based on parsing the text) whether the note in it is also implicit from its text. It would then maybe add any other quotes that let me know the other contexts in which this conversion may fail to happen implicitly, or explain there are no more such contexts. Perhaps a general discussion of why glvalue to prvalue is considered a conversion.

2 Answers
Related