我环顾网络,找到了an article which tries to explain std::move
and rvalues并找到了我无法掌握的东西。
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引用,这也是不可能的,因为引用必须指向某个东西。但在当下的热度中,我满满的.......
答案 0 :(得分:3)
int& foo()
是一个返回(lvalue)引用整数的函数。
引用就像一个指针,但与指针不同,它没有自己的标识。它在逻辑上是其目标的别名,而不是其目标的地址。
引用经常被实现为指针,但引用点通常是编译器可以完全删除它们的存在。使用指针这样做通常更加困难,因为它们具有与它们所引用的不同的身份。
C ++中无法获取引用的地址。您可以获取包含引用的结构的地址,该结构非常接近,但没有区别,但您无法获取引用本身的地址。
int& foo()
返回对整数的引用。举个例子:
int x=0, y=0;
bool pick_x=true;
int& foo() { if (pick_x) return x; else return y; }
现在foo
会返回对x
或y
的引用,具体取决于pick_x
的状态。
您可以使用foo
的返回值,就像它是x
一样(或y
如果!pick_x
。)
lvalue和rvalue来自C的日子。左值是一个表达式,可以在=
符号的左或右上,而rvalue是一个表达式,可以只能使用=
符号的右侧。
在许多语言中,左值和右值可以用语法表示。在C ++中,引用的存在意味着表达式的返回值可以是要分配的有效内容,并且重载operator=
的存在意味着有时可以分配rvalues。事情变得棘手。
在C ++ 11中,添加了左值引用和右值引用。每个拒绝绑定到其他类型的表达式。还有转发引用,主要出现在模板类型推导中。
答案 1 :(得分:0)
非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);
}