In my effort to understand rvalue references, I have been pondering when the compiler will determine that a particular function argument is an rvalue reference, and when it will determine it to be an lvalue reference.
(This issue is related to reference collapsing; see Concise explanation of reference collapsing rules requested: (1) A& & -> A& , (2) A& && -> A& , (3) A&& & -> A& , and (4) A&& && -> A&&).
In particular, I have been considering if the compiler will always treat unnamed objects as rvalue references and/or if the compiler will always treat temporary objects as rvalue references.
In turn, this leads me to question whether unnamed objects are equivalent to temporary objects.
My question is: Are unnamed objects always temporary; and are temporary objects always unnamed?
In other words: Are unnamed objects and temporary objects equivalent?
I assume you are talking about function templates with universal reference parameters, like this?
The rules are very simple. If the argument is an rvalue of type
X, thenTwill be deduced to beX, henceT&&meansX&&. If the argument is an lvalue of typeX, thenTwill be deduced to beX&, henceT&&meansX& &&, which is collapsed intoX&.If you were really asking about arguments, then the question does not make much sense, because arguments are never lvalue references or rvalue references, because an expression of type
X&is immediately converted to an expression of typeX, which denotes the referenced object.But if you actually meant “How does the compiler distinguish lvalue arguments from rvalue arguments?” (note the missing reference), then the answer is simple: the compiler knows the value category of every expression, because the standard specifies for every conceivable expression what its value category is. For example, the call of a function is an expression that can belong to one of three value categories:
(Provided, of course, that
Xitself is not a reference type.)If none of this answers your question, please clarify the question. Also, somewhat relevant FAQ answer.