c++:函数左值或右值
Posted
技术标签:
【中文标题】c++:函数左值或右值【英文标题】:c++: function lvalue or rvalue 【发布时间】:2012-12-13 06:49:34 【问题描述】:我刚开始通过阅读this page 了解 c++11 中的右值引用,但我被困在了第一页。这是我从该页面获取的代码。
int& foo();
foo() = 42; // ok, foo() is an lvalue
int* p1 = &foo(); // ok, foo() is an lvalue
int foobar();
j = foobar(); // ok, foobar() is an rvalue
int* p2 = &foobar(); // error, cannot take the address of an rvalue
-
为什么
foo()
是左值?是不是因为foo()
返回的int&
基本上是一个左值?
为什么foobar()
是右值?是因为foobar()
返回int
吗?
一般来说,您为什么要关心函数是否为右值?我想如果我阅读了那篇文章的其余部分,我会得到答案。
【问题讨论】:
【参考方案1】:L-Values 是位置,R-Values 是 可存储 值(即,可以分配的值:例如,命名空间是 不可 可分配的;感谢 @ Maggyero 的编辑建议)。
所以:
-
因为
foo()
返回一个引用(int&
),所以它本身就是一个左值。
正确。 foobar()
是一个右值,因为 foobar()
返回 int
。
我们不太关心函数是否为 R 值。我们对 R-Value 参考感到兴奋。
你指的那篇文章很有趣,我之前没有考虑过转发或在工厂中使用。我对 R-Value 引用感到兴奋的原因是移动语义,例如:
BigClass my_function (const int& val, const OtherClass & valb);
BigClass x;
x = my_function(5, other_class_instance);
在该示例中,x 被销毁,然后 my_function 的返回值通过复制构造函数复制到 x 中。为了从历史上解决这个问题,你可以这样写:
void my_function (BigClass *ret, const int& val, const OtherClass & valb);
BigClass x;
my_function(&x, 5, other_class_instance);
这意味着现在my_function
有副作用,而且它不是那么容易阅读。现在,使用 C++11,我们可以改为:
BigClass & my_function (const int& val, const OtherClass & valb);
BigClass x;
x = my_function(5, other_class_instance);
让它像第二个例子一样高效地运行。
【讨论】:
‘R 值是实际值’ 更准确地说,R 值是 可存储 值。有些值不能在 C++ 中赋值,因此不是 R 值,例如一个类型,一个命名空间。 @Maggyero 命名空间和类型根本不是值。并非所有有名字的东西都是值 @Caleth 值是表达式的含义。由于命名空间和类型并非毫无意义,它们确实具有价值。你可以看看 Dana Scott 和 Christopher Strachey 在指称语义方面的工作。我不认为 C++ 的指称语义已经发布。目前,它仅在 ISO C++ 标准中以自然语言指定。 @Maggyero C++ 标准讨论了basic.lval 中的值,命名空间和类型不是表达式(尽管命名空间名称和类型名称可以与表达式一起出现)“glvalue 的结果是表示的实体纯右值的结果是表达式存储到其上下文中的值;类型为 cv void 的纯右值没有结果。结果为值 V 的纯右值有时被称为具有或命名为值 V。 " @Caleth 指称语义中的value(或denotation)在ISO C++ 标准的术语中称为entity。指称语义中的stored value(或存储的指称)在ISO C++ 标准中称为value。命名空间和类型是指称语义术语中的值,是 ISO C++ 标准中的实体。以上是关于c++:函数左值或右值的主要内容,如果未能解决你的问题,请参考以下文章