I'm sorry for the broadness of the question, it's just that all these details are tightly interconnected..
I've been trying to understand the difference between specifically two value categories - xvalues and prvalues, but still I'm confused.
Anyway, the mental model I tried to develop for myself for the notion of 'identity' is that the expression that has it should be guaranteed to reside in the actual program's data memory.
Like for this reason string literals are lvalues, they're guaranteed to reside in memory for the entire program run, while number literals are prvalues and could e.g. hypothetically be stored in straight asm.
The same seems to apply to std::move
from prvalue literal, i.e. when calling fun(1)
we would get only the parameter lvalue in the callee frame, but when calling fun(std::move(1))
the xvalue 'kind' of glvalue must be kept in the caller frame.
However this mental model doesn't work at least with temporary objects, which, as I understand, should always be created in the actual memory (e.g. if a rvalue-ref-taking func is called like fun(MyClass())
with a prvalue argument). So I guess this mental model is wrong.
So what would be the correct way to think about the 'identity' property of xvalues? I've read that with identity I can compare addresses but if I could compare addresses of 2 MyClass().member
s (xvalue according to the cppreference), let's say by passing them by rvalue refs into some comparison function, then I don't understand why I can't do the same with 2 MyClass()
s (prvalue)?
One more source that's connected to this is the answer here: What are move semantics?
Note that even though std::move(a) is an rvalue, its evaluation does not create a temporary object. This conundrum forced the committee to introduce a third value category. Something that can be bound to an rvalue reference, even though it is not an rvalue in the traditional sense, is called an xvalue (eXpiring value).
But this seems to have nothing to do with 'can compare addresses' and a) I don't see how this is different from the 'traditional sense' of the rvalue; b) I don't understand why such a reason would require a new value category in the language (well, OK, this allows to provide dynamic typing for objects in OO sense, but xvalues don't only refer to objects).