首页 > 解决方案 > 为什么 int foo() 是一个右值,而 int& foo() 在这个例子中是一个左值?

问题描述

我们有以下代码示例:

// lvalues:
  //
  int i = 42;
  i = 43; // ok, i is an lvalue
  int* p = &i; // 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 foobar();

应该是一个右值,而相同的函数但具有对象引用作为返回类型,如下所示:

int& foobar();

是一个左值。(第二部分很自然,因为我们在定义函数时特别要求并因此保留引用。但是,第一个示例对我来说很难掌握,因为我期望函数的内存位置以某种方式隐式扣除,基于这样的假设——这可能是错误的——每个函数在内存中都有自己的、不可更改的位置,总之,第一个示例也应该是一个左值引用)。请先尝试解释这方面。

我明白那个:

左值是一个引用内存位置的表达式,它允许我们通过 & 运算符获取该内存位置的地址。右值是不是左值的表达式。

但是,如上所述,我最感兴趣的是如何处理与简单对象相反或相关的函数,以考虑左值/右值概念。

谢谢!

标签: c++rvalue-referencelvalue

解决方案


foobar()不是函数。这是一个函数调用。它的评估是调用函数的结果,即一个int是右值的结果。

以下是如何将函数分配给引用(这是一个比获取地址更好的测试):

int (&a)() = foo; // OK
int (&&b)() = foo; // OK

这就是分配函数地址的方式

int (*a)() = &foo; // OK

我理解:“左值是一个引用内存位置的表达式,它允许我们通过 & 运算符获取该内存位置的地址。右值是一个不是左值的表达式。”

嗯......这是一个非常简单的定义。如果您对该主题感兴趣,这里有一些链接:

什么是 rvalues、lvalues、xvalues、glvalues 和 prvalues?

价值类别


推荐阅读