【发布时间】:2018-01-01 05:36:39
【问题描述】:
我很抱歉这个问题太宽泛了,只是所有这些细节都紧密相连..
我一直试图了解具体两个值类别之间的区别 - xvalues 和 prvalues,但我仍然感到困惑。
无论如何,我试图为自己开发的“身份”概念的心智模型是,应该保证拥有它的表达式驻留在实际程序的数据内存中。
出于这个原因,字符串文字是左值,它们保证在整个程序运行期间驻留在内存中,而数字文字是纯右值并且可以例如假设存储在直接 asm 中。
这似乎同样适用于纯右值文字中的std::move,即当调用fun(1) 时,我们只会在被调用者框架中获得参数左值,但是当调用fun(std::move(1)) 时,必须保留glvalue 的xvalue '种类'在调用者框架中。
但是,这种心智模型至少不适用于临时对象,据我所知,它们应该始终在实际内存中创建(例如,如果像 fun(MyClass()) 那样调用带有右值的右值引用函数争论)。所以我猜这个心智模型是错误的。
那么思考 xvalue 的“身份”属性的正确方法是什么?我已经读过,我可以通过身份比较地址,但是如果我可以比较 2 个MyClass().members 的地址(根据 cppreference 的 xvalue),假设通过 rvalue refs 将它们传递给某个比较函数,那么我不明白为什么我不能对 2 MyClass()s (prvalue) 做同样的事情?
与此相关的另一个来源是这里的答案: What are move semantics?
请注意,即使 std::move(a) 是一个右值,它的求值也不会创建一个临时对象。这个难题迫使委员会引入第三个价值类别。可以绑定到右值引用的东西,即使它不是传统意义上的右值,也称为 xvalue(eXpiring 值)。
但这似乎与“可以比较地址”无关,并且 a) 我看不出这与右值的“传统意义”有何不同; b)我不明白为什么这样的原因需要语言中的新值类别(好吧,这允许为 OO 意义上的对象提供动态类型,但 xvalues 不仅仅指对象)。
【问题讨论】:
-
注意新规则 (c++17) 重新定义了纯右值并引入了纯右值到极值的转换,“临时物化”。如果您尝试将两个 MyClass() 纯右值传递给比较函数,它们将作为引用初始化的一部分进行此转换。
-
@Cubbi 嗯,你的意思是 C++17 还与我试图提出的这个“保证存储在内存中”的概念更加一致,或者实现的理由纯粹是保证省略?我知道这个概念与标准的字眼相去甚远,但从外部角度来看,它似乎确实符合事物的定义方式。
-
似乎更一致,是的。 C++14 rvalue ref 将“直接”绑定到类纯右值和类 xvalue 初始化程序。 ([dcl.init.ref]/5.2)。现在它直接绑定到 xvalues,但转换 prvalues 并绑定到结果 xvalues。
标签: c++ c++14 xvalue value-categories prvalue