Are unnamed objects and temporary objects equivalent?

In an attempt to understand rvalue references, I reflected when the compiler determines that the particular function argument is an rvalue reference, and when it defines it as a lvalue reference.

(This problem is related to link folding, see a brief description of the requested link folding rules: (1) A & and β†’ A &, (2) A && & β†’ A &, (3) A &&> A & and (4) A && & && & &&& & ).

In particular, I consider whether 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 makes me wonder if unnamed objects are equivalent to temporary objects.

My question is: unnamed objects are always temporary; and temporary objects always unnamed?

In other words: are named objects and temporary objects equivalent?

+6
source share
3 answers

I speculated when the compiler determines that a particular function argument is an rvalue reference, and when it defines it as an lvalue reference.

I assume you are talking about function templates with universal reference parameters , eg:

template<typename T> void foo(T&& t) { } 

The rules are very simple. If the argument is an rvalue of type X , then T will be output as X , so T&& means X&& . If the argument is an lvalue of type X , then T will be output as X& , so T&& means X& && , which is collapsed into X& .

If you really asked about the arguments , then the question does not make much sense because the arguments never refer to references or references to rvalue, because an expression of type X& immediately converted to an expression of type X , which denotes a reference object.

But if you really meant "How does the compiler distinguish between lvalue arguments and rvalue arguments?" (note the missing link ), then the answer is simple: the compiler knows the category of values ​​for each expression, because the standard defines for each conceivable expression what its category of values ​​is. For example, a function call is an expression that can belong to one of three categories of values:

 X foo(); // the expression foo() is a prvalue X& bar(); // the expression bar() is an lvalue X&& baz(); // the expression baz() is an xvalue 

(Provided, of course, that X itself is not a reference type.)

If this does not answer your question, clarify this question. In addition, several answers to frequently asked questions .

+2
source

Maybe I'm wrong, because I'm not sure what the definition of "unnamed object" is. But consider the argument to the foo () function below:

 void foo(int) { /* ... */ } int main() { foo(5); } 
Argument

foo () is not specified, but it is not temporary. Therefore, unnamed objects and temporary objects are not equivalent.

+3
source

Temporary objects can be named.

A very common case is when it is passed as a parameter to a function. Another less common case is the binding of a constant reference to the rvalue result for a function.

 int f(int i) { return i + 1; } int g() { const int &j = f(1); return j; } 

Object objects are often temporary, but not always. For example, an anonymous union object:

 struct S { union { int x; char y; }; } s; 

And, of course, any object created by operator new .

Perhaps there are other cases, but even they can serve as counterexamples for the hypothesis :)

+3
source

All Articles