右值和左值之间的确切区别
当我阅读http://thbecker.net/articles/rvalue_references/section_01.html时,我得到了以下snippiest。
// lvalues:
//
int i = 42;
i = 43; // ok, i is an lvalue
int& foo();
foo() = 42; // ok, foo() is an lvalue
int* p1 = &foo(); // ok, foo() is an lvalue
// rvalues:
//
int foobar();
int j = 0;
j = foobar(); // ok, foobar() is an rvalue
int* p2 = &foobar(); // error, cannot take the address of an rvalue
j = 42; // ok, 42 is an rvalue
为什么int * p2 =&foobar(); 是错误语句,而int * p1 =&foo(); 不是一个错误。 如果后面的一个是左值,而第一个是右值?
提前致谢
所以我们有两个功能:
int& foo();
int foobar();
foo
是一个函数,返回int值的左值 foobar
是一个返回int的函数 函数调用表达式:
foobar()
foo()
都有类型int(引用从表达式中删除,所以foo()
类型是int
而不是lvalue-reference to int
)。 这两个表达式具有不同的值类别:
foobar()
是一个prvalue(对返回非引用的函数的函数调用是一个prvalue) foo()
是一个左值(对函数的函数调用返回一个左值引用是一个左值) 你不能取一个右值的地址(一个前值是一种右值),所以&foobar()
是不允许的。
你可以把左值的地址作为&foo()
允许的。
假设我们在C中有下面的示例代码。它会编译吗? 左值和右值的概念如何在这个问题中起作用?
#define X 8
int main(void)
{
++X; // will this line compile?
return 0;
}
左值和右值的概念必须解释一下,才能真正理解上面的代码和被问到的问题。 在我们开始之前,您应该注意到,这里给出的左值和右值的定义并不准确,因为即使C标准本身在定义上也相当模糊。
rvalues和左值的区别
一个对象是一个可以检查的内存区域,但不一定需要修改。 左值是引用这样一个对象的表达式。 术语左值最初是指出现在表达式的左侧(因此是'l')手边的对象。 该定义不再适用,因为任何const限定类型也被认为是左值,但它永远不会出现在赋值语句的左侧,因为它不能被修改。 因此,术语“可修改的左值”被创建用于指代可以被修改的左值,并且const限定的类型不属于该类别。
右值是任何具有值的表达式,但不能赋值给它。 人们也可以说右值是任何不是左值的表达式。 一个右值的例子是一个字面常量 - 例如'8'或'3.14'。 所以,上面代码中的值'8'显然是一个右值。
用我们对左值和右值的理解来回答这个问题
现在我们来尝试解决这个问题。 严格地说,前缀(或后缀)增量运算符的操作数必须是可修改的左值。 那么,在我们的代码中,前缀增量运算符的操作数是什么?
由于X是一个宏,在预处理器运行后,上面的语句将扩展为“++ 8”。 这意味着“8”是前缀增量运算符的操作数。 而且,因为8是一个右值,所以它不能用作“++”的参数。 这反过来又意味着上面的代码不会被编译。
链接地址: http://www.djcxy.com/p/40291.html上一篇: Exact difference between rvalue and lvalue
下一篇: c++