sky*_*ack 10 c++ move rvalue xvalue c++11
考虑下面的最小例子:
#include<utility>
struct S { };
int main() {
S s;
std::move(s) = S{};
}
Run Code Online (Sandbox Code Playgroud)
它编译没有错误.
如果我改用非类型,我会收到错误.
例如,下面的代码无法编译:
#include<utility>
int main() {
int i;
std::move(i) = 42;
}
Run Code Online (Sandbox Code Playgroud)
枚举,作用域枚举等也会发生同样的情况.
错误(来自GCC)是:
使用xvalue(rvalue reference)作为左值
这背后的理由是什么?
我想这是正确的,但我想了解我能用所有类型而不是非类型的方式做到这一点的原因.
小智 5
C++允许赋值给类对象rvalues,但不允许赋值为基本类型rvalues;
一个例子,
string s1, s2;
s1 + s2 = "asdf"; // ok since rvalue s1 + s2 is an object
int i1, i2;
i1 + i2 = 10; // error, since i1 + i2 is a primitive type
Run Code Online (Sandbox Code Playgroud)
同样的规则适用于您的问题.std :: move(s)返回对象类型的右值,但是std :: move(i)返回基本类型的右值.
\n我正在尝试用一堆标准链接来回答我自己的问题。
\n我很确定我会写出一些非常错误的东西,并且有人会来跟我批驳。
\n好吧,我尽力解释如何从标准中推断出问题中所描述的内容。
\n如果需要,请随意投反对票,但请让我知道出了什么问题,以便能够修复答案并理解错误。
\n谢谢。\n
3.9/8(类型):
\n\n\n\n\nAn\xc2\xa0对象类型\xc2\xa0 是一个(可能是 cv 限定的)类型,它不是函数类型,不是引用类型,也不是 \xc2\xa0 cv void。
\n
5.2.2/10(表达式、函数调用):
\n\n\n\n\n如果结果类型是对象类型的右值引用,则函数调用是 [...] xvalue
\n
因此std::move是一个x 值表达式。
5.18/3(作业):
\n\n\n\n\n如果左操作数不是类类型,则表达式将隐式转换 [...] 为左操作数的 cv 非限定类型。
\n
这不会添加有用的信息,但这是为了完整性。
\n\n\n 4.1/2(左值到右值的转换):
\n\n\n否则,如果\xc2\xa0T\xc2\xa0具有类类型,则转换从泛左值复制初始化\xc2\xa0T\xc2\xa0类型的临时值,并且转换的结果是该临时值的纯右值。
\n\n否则,左值指示的对象中包含的值是纯右值结果。
\n
12.2(临时对象)完成剩下的工作。
\n\n因此,正如 @xaxxon 在评论中提到的,我实际上正在尝试执行(让我写)42 = 0;,但它不是 C++ 中的有效表达式。\n
正如 @bogdan 的评论中正确指出的那样,在这种情况下要引用的标准的正确部分是5.18/1(分配):
\n\n\n\n\n\n所有这些都需要一个可修改的左值作为其左操作数 [...]
\n
| 归档时间: |
|
| 查看次数: |
336 次 |
| 最近记录: |