What are rvalues, lvalues, xvalues, glvalues, and prvalues?很好地概述了rvalues/lvalues的分类法,该问题的最新答案之一(https://stackoverflow.com/a/9552880/368896)强调了prvalues类似于旧式rvalues,而新的xvalues则允许“类似于lvalues” ”行为。
但是,请考虑以下代码:
class X {};
X foo() { return X(); }
int main()
{
foo() = X(); // foo() is a prvalue that successfully appears on the lhs
}
在此示例中,表达式
foo()
是出现在左侧的prvalue,并接受赋值。这让我思考-“xvalues”与“prvalues”不同的逻辑是因为xvalues(它们是glvalues)可以出现在左侧,在本示例中似乎被破坏了。在这里,我们有一个prvalue-不是glvalue-在lhs上成功显示并接受分配。
(注意:对于POD,上面的示例无法编译,因此对于POD,xvalues和prvalues之间的区别似乎是有意义的。因此,此问题专门针对非POD类型。)
那么,x值和pr值之间在允许的用法或行为上的真正区别是什么,需要将此区别写入标准中?一个区别的例子就是一个很好的替代答案。
ADDENDUM
Pubby的评论是正确的。 prvalue的生存期由编译器延长,但xvalue的生存期未延长。
因此,这是问题的答案:
考虑以下代码:
// ***
// Answer to question, from Pubby's comment
// ***
class X
{
public:
X() : x(5) {}
int x;
};
X foo() { return X(); }
X&& goo() { return std::move(X()); } // terrible coding, but makes the point
int main()
{
foo() = X();
X&& x1 = foo(); // prvalue - lifetime extended! Object resides directly on stack as return value
X&& x2 = goo(); // xvalue - lifetime not extended. Object (possibly polymorphic) resides somewhere else.
x1.x = 6;
x2.x = 7; // Danger!
std::cout << x1.x << std::endl; // Just fine
std::cout << x2.x << std::endl; // prints garbage in VS 2012
}
这说明了prvalue和xvalue在行为上的差异。除了绑定(bind)的不同(prvalue与xvalue)以外,这里我们有相同的客户端代码。
如示例代码所示,prvalue的生存期会自动延长,而xvalue的生存期不会自动延长。
还有其他明显的区别:对于prvalue,对象本身作为函数的返回值出现在堆栈上;相应地,由于保证prvalue的静态类型是其动态类型(请参见下面的答案),因此延长其生存期是有意义的,并且可以由编译器完成。
另一方面,对于xvalue,对象位于某个未知的任意位置,因此编译器无法轻松地延长其生存期,尤其是考虑到类型可以是多态的。
感谢您的回答。
最佳答案
对于多态非Pod类型的xvalue表达式,通常在编译时不知道该表达式的动态类型(因此,将评估它们上的typeid表达式,并且通常不能对虚拟函数调用进行虚拟化)。
对于prvalue,这不适用。动态类型等于静态类型。
另一个区别是decltype(e)
是xvalues的rvalue引用类型,而prvalues是非引用类型。
另一个不同之处是,不对prvalue进行从左值到右值的转换(它们已经是结果将产生的值)。这可以通过一些很奇怪的代码来观察
struct A {
int makeItANonPod;
A() = default;
private:
int andNonStdLayout;
A(A const&) = default;
};
void f(...);
int main() {
f(A()); // OK
f((A&&)A()); // illformed
}
关于c++ - 对于非POD对象,xvalue和prvalue之间在允许的用法或行为上存在差异的示例是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15482508/