c++ - 右值和左值之间的确切区别

标签 c++ c++11 rvalue

当我在阅读时 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();不是错误。多晚一个是左值,第一个是右值?

最佳答案

假设我们有下面显示的 C 示例代码。它能编译吗?左值和右值的概念如何解决这个问题?

#define X 8
int main(void)
{
    ++X; // will this line compile?
        return 0;

}

为了真正理解上面的代码和提出的问题,必须稍微解释一下左值和右值的概念。在我们继续之前,您应该注意这里给出的左值和右值的定义并不准确,因为甚至 C 标准本身在定义上也相当模糊。

右值和左值的区别

对象是可以检查但不一定可以修改的内存区域。左值是引用此类对象的表达式。术语左值最初指的是出现在表达式左侧(因此是“l”)的对象。该定义不再适用,因为任何 const 限定类型也被视为左值,但它永远不会出现在赋值语句的左侧,因为它无法修改。因此,创建了术语“可修改左值”来指代可以修改的左值,而 const 限定类型不属于此类。

右值是任何具有值但不能为其分配值的表达式。也可以说右值是任何不是左值的表达式。右值的一个例子是文字常量——比如“8”或“3.14”。所以,上面代码中的值“8”显然是一个右值。

利用我们对左值和右值的理解来回答问题

现在让我们尝试解决这个问题。严格来说,前缀(或后缀)增量运算符的操作数必须是可修改的左值。那么,我们上面代码中前缀自增运算符的操作数是多少呢?

由于 X 是一个宏,上面的语句在预处理器运行后将扩展为“++8”。这意味着“8”是前缀增量运算符的操作数。而且,因为 8 是一个右值,所以它不能用作“++”的参数。反过来,这意味着上面的代码将无法编译。

关于c++ - 右值和左值之间的确切区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17357888/

相关文章:

c++ - C++ 中的超时变量使用什么类型?

c++ - Lambda 捕获 constexpr 对象

C++ 在类中定义 RValue 属性

c++ - 一个 dfm 中的多个对话框

c++ - MPI_DOUBLE_INT 和 C++ 结构

C++ 期望主表达式在 "int"之前

c++ - "unresolved overloaded function type"在 std::function 中有静态函数

c++ - 返回对此的右值引用的正确方法

c++ - c++ 中的右值如何存储在内存中?

android - 在 C++ 中从 qt 获取 Android 客户经理