右值和左值之间的确切区别

当我阅读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++