函数返回 int&

Function returning int&

本文关键字:int 返回 函数      更新时间:2023-10-16

我在网上找了一篇试图解释std::move和右值的文章,发现了一些我真的无法理解的东西。

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

int& foo()的意义是什么?这个例子中的foo() = 42是什么?

编辑:因为让我困惑的部分和右值没有任何关系,我将写解决我问题的部分:

我不知道你可以在作用域中写函数声明所以int&Foo()变成了一个带空初始化项的int引用,这也是不可能的,因为引用必须指向某些东西。但在最激动的时刻,我吃饱了.......

int& foo()是一个返回(左值)整数引用的函数。

引用类似于指针,但与指针不同的是,它没有自己的标识。逻辑上,它是目标的别名,而不是目标的地址。

引用通常被实现为指针,但引用的意义在于编译器通常可以完全删除它们的存在。对于指针来说,这样做通常比较困难,因为它们的标识与它们所指的对象是分开的。

在c++中没有办法获得引用的地址。你可以得到包含引用的结构体的地址,两者非常接近,没有什么区别,但是你不能得到引用本身的地址。

int& foo()返回对整数的引用。例如:

int x=0, y=0;
bool pick_x=true;
int& foo() { if (pick_x) return x; else return y; }

现在foo返回对xy的引用,具体取决于pick_x的状态。

您可以使用foo的返回值几乎与x完全相同(如果!pick_x则为y)

左值和右值来自c的年代。左值是一个表达式,可以在=符号的左或右,右值是一个表达式,只能在=符号的

在许多语言中,左值和右值都可以在语法中表示。在c++中,引用的存在意味着表达式的返回值可以是可以赋值的有效对象,而重载operator=的存在意味着右值有时可以赋值。所以事情变得棘手了。

在c++ 11中,增加了左值引用和右值引用。每个都拒绝绑定到其他类型的表达式。还有转发引用,主要发生在模板类型演绎中。

非const左值引用的语义与普通指针的语义完全相同,只是指针需要*操作符来解引用,而引用则不需要。

所以你的

int& foo();
foo() = 42;

可以用指针重新表示为

int* foo();
*foo() = 42;

如果你在第二段代码中没有看到任何奇怪或不寻常的东西,那么你应该在第一段代码中也没有看到任何奇怪或不寻常的东西。

例如

int i;
int &foo() { return i; }
int *bar() { return &i; }
int main()
{
  foo() = 42;
  assert(i == 42);
  *bar() = 24;
  assert(i == 24);
}