c++ - 为什么 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();
是一个左值。(第二部分很自然,因为我们在定义函数时特别要求并因此保留引用。但是,第一个示例对我来说很难掌握,因为我期望函数的内存位置以某种方式隐式扣除,基于这样的假设——这可能是错误的——每个函数在内存中都有自己的、不可更改的位置,总之,第一个示例也应该是一个左值引用)。请先尝试解释这方面。
我明白那个:
左值是一个引用内存位置的表达式,它允许我们通过 & 运算符获取该内存位置的地址。右值是不是左值的表达式。
但是,如上所述,我最感兴趣的是如何处理与简单对象相反或相关的函数,以考虑左值/右值概念。
谢谢!
解决方案
foobar()
不是函数。这是一个函数调用。它的评估是调用函数的结果,即一个int
是右值的结果。
以下是如何将函数分配给引用(这是一个比获取地址更好的测试):
int (&a)() = foo; // OK
int (&&b)() = foo; // OK
这就是分配函数地址的方式
int (*a)() = &foo; // OK
我理解:“左值是一个引用内存位置的表达式,它允许我们通过 & 运算符获取该内存位置的地址。右值是一个不是左值的表达式。”
嗯......这是一个非常简单的定义。如果您对该主题感兴趣,这里有一些链接:
推荐阅读
- r - 创建一个函数来手动计算 R 中的 VIF 值
- java - “Java中的同步块在某个对象上同步”是什么意思..?
- aurelia - 如何在 SystemJS+TS 中显式包含 aurelia-dialog@2.0.0-rc.3 的资源?
- c++ - boost Spirit V2 Qi 语法线程安全吗?
- rabbitmq - 消息系统可靠性
- c# - 通用列表:添加、查找、删除 C#
- javascript - React Carousel renderArrow consts 未定义
- login - Yii2 登录验证密码失败
- ms-access - 使用权。如果记录为空,我该如何更改?
- swift - 使用 RxSwift 联网