c++ - 左值真的是非临时对象吗?

标签 c++ c++11

虽然不是实际标准,但我依赖 this page在 cppreference.com 上查看此特定措辞:

An lvalue is an expression that identifies a non-temporary object or a non-member function.

The following expressions are lvalues:

  • The name of a variable or function in scope, regardless of type, such as std::cin or std::endl. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression.

...

我对上面引用的部分的(简化)理解是左值:

  1. 仅供引用
  2. 不得是临时对象

我知道引用不是对象,因此第 2 点必须意味着就引用而言,它不能引用临时对象。但是,从表达式本身来看,这是否意味着对临时变量的引用不是左值?您可以引用临时非临时对象:

int myvar = 0;
int& ref_myvar = myvar; // Reference to non-temporary

class foo {};
foo const& ref_foo = foo{}; // Reference to temporary

在上面的代码片段中,稍后在单独的表达式中使用 ref_foo 是否是左值?右值引用有一条规则,规定在表达式中按名称使用的右值引用仍然是左值(因为您引用了此时的名称)。此规则是否也适用于左值引用(因为它们也有名称,并且在表达式中使用名称本身将使其成为左值,就像对右值引用变量一样)?

我希望我说得有道理。至少我希望我的困惑的根源是显而易见的。有关如何在表达式中使用上面的左值引用来证明与我的问题相关的一些观点的一些示例也将有很大的帮助。

最佳答案

我想说,cppreference 措辞对于“一般介绍”级别的讨论,甚至对于“大多数日常用途”级别的讨论来说都是可以的。然而,一旦您了解了精细的技术细节,这样的陈述可能会变得有些误导。

重要的一点是,值类别(“作为左值”)是表达式的属性,而不是对象的属性。您可以拥有一个临时对象通过左值访问,并且可以通过右值访问非临时对象。

引用您的示例:

ref_myvarref_foo 都是左值,并且始终如此,无论您如何使用它们。具体如下:

foo&& rref = foo{};

rref 也是并且永远都是左值。它是对右值的引用,但引用本身有名称,左值也是如此。

如果您想将左值视为右值,请使用标准提供的大小写运算符:

rvalue = std::move(lvalue);

让我们分析一下这段代码:

int someint = std::move(ref_myvar);

ref_myvar 是一个左值。 std::move(ref_myvar) 是一个右值。 someint 是一个左值。


我认为没有一种简洁的方法可以在不完全标准化的情况下定义左值,但是名称(或缺少名称)在大多数定义中起着重要作用。我将尝试给出这样的定义;这些是左值:

  • 作为名称的表达式,枚举器和成员函数除外。
  • “对某物的左值引用”类型的表达式。
  • 取消引用指针的结果。

请注意,ref_myvarref_foorref 都是左值,因为它们有名称。 std::move(ref_myvar) 没有名称,因此它是一个右值。

关于c++ - 左值真的是非临时对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32054791/

相关文章:

c++ - QString 通过引用传递问题

c++ - seekg() 神秘地失败

c++ - for循环c++中的“冒号”和 'auto'?需要一些帮助来理解语法

c++ - 调用模板显式实例化时如何开启自动匹配?

c++ - 使用 c++0x Lambda 表达式时调用不匹配

c++ - 如何在不使用 C++ 中的任何库的情况下检测图像中的对象?

c++ - "va_start"的第二个参数

c++ - 无法使用 std::for_each() 和 std::bind() 过滤 vector 中的元素并将这些过滤后的元素放入新 vector 中

c++ - Variadic 模板,没有匹配的调用函数

arrays - 如何在不排序的情况下找到数组中最小的数字?