Are temporary objects xvalues?
Asked Answered
I

1

8

I am currently writing my degree dissertation and it involves also some explaining of the theory behind C++11 which is really fine as C++ is my programming language of choice and the standard is more or less available for free (N3337) to get yourself lost in.

Yet I have hit a wall while trying to explain the new xvalue category accurately and in detail. It is my understanding that a temporary object is always a xvalue but I cannot find any reference to this in the standard. It is my understanding that the value category of an expression of a function call to a function that has a non-reference return type, is a xvalue. The standard says that "a xvalue is the result of certain kind of expressions that involve rvalue-references" which is bugging me. For example:

TestClass { ... };
testClass createObject() { return testClass(); }

void someFunction(TestClass& testClass) { ... }
void someFunction(TestClass&& testClass) { ... }

someFunction(createObject());

The above will, as expected, call the overloaded function which takes an rvalue-reference as parameter. Yet createObject() does not return a rvalue-reference, it returns a temporary object of type TestClass. My problem is now, I have to explain the reasons behind it. What does the expression "createObject()" evaluate to? If it is indeed a xvalue because it returns a temporary object, the reasoning behind it is clear and the rvalue-reference is favored during overload resolution. If it does not, what is the explanation for this behaviour with regard to the standard? Is there some implicit conversion logic defined somewhere that I haven't found yet?

I'd really appreciate if someone could help me out on this one because even after days of digging and reading, I have yet to come up with a sound explanation. Thanks a lot in advance.

Ingenious answered 12/3, 2012 at 16:28 Comment(1)
related questionSegment
S
13

Objects are never {l|r|x}values. value categories describe expressions.

xvalue is the value category of the function call expression where the function return type is an rvalue reference to object (e.g. std::move), and it is also the value category of the cast expression where the cast is to an rvalue reference to object (e.g. the guts of std::move).

The function call expression createObject() in your example is an prvalue expression because it is a function call to a function with non-reference return type.

Speakeasy answered 12/3, 2012 at 16:32 Comment(5)
I know the categories only apply to expressions. :) Sorry, I was unclear in my post and will correct it momentarily. Do I feel stupid now - really stupid. I don't know what I was thinking expecting the expression of a function call with a non-reference return type to be a xvalue. Thanks a lot. And I better go away and hide now... :(Ingenious
"Objects are never {l|r|x}values." but xvalues denote an object usually near the end of its lifetime. So if I have T t = T() the T() prvalue is converted to xvalue; this xvalue refers to a temporary of type T. This implicitly is something like T _tmp{}; T t = _tmp. the first _tmp is lvalue expression. And the last _tmp is xvalue expression. Am I right?Ritualist
@cpper it is implicitly (or explicitly, if you look at generated AST) something like T t = materialize( T() ), where T() is rvalue, and materialize(T()) is xvalue. I don't follow the _tmp part of the comment.Speakeasy
Does materialize() (method?) even exist in the standard? Please can you give me a reference to read on that?Ritualist
@cpper no, it exists as a node in the AST The standard just a verbal description of what it does in [conv.rval]Speakeasy

© 2022 - 2024 — McMap. All rights reserved.