Consider the minimal example below:
#include<utility>
struct S { };
int main() {
S s;
std::move(s) = S{};
}
It compiles with no errors.
If I use non class types instead, I get an error.
As an example, the code below doesn't compile:
#include<utility>
int main() {
int i;
std::move(i) = 42;
}
The same happens with enums, scoped enums, and so on.
The error (from GCC) is:
using xvalue (rvalue reference) as lvalue
What's the rationale behind this?
I guess it's right, but I'd like to understand what's the reason for which I can do that with all the types but the non class ones.
I'm trying to reply to my own question with a bunch of links to the standard.
I'm quite sure that I'll write something that is terribly wrong and someone will come banding words with me.
Well, I did my best to explain how one can deduce from the standard what's described in the question.
Feel free to downvote if needed, but please let me know what's wrong so as to be able to fix the answer and understand the error.
Thank you.
3.9/8 (types):
5.2.2/10 (expressions, function call):
Thus
std::move
is an xvalue expression in either cases.5.18/3 (assignment):
This does not add useful information, but it's for the sake of completeness.
4.1/2 (lvalue-to-rvalue conversion):12.2 (temporary objects) does the rest.
So, as mentioned by @xaxxon in the comments, I was actually trying to do (let me write)
42 = 0;
and it is not a valid expression in C++.As correctly pointed out in the comments by @bogdan, the right part of the standard to which to refer in this case is 5.18/1 (Assignment):
While 5/2 and 5/3 clarify that the statement applies to built-in operators only.