来自:Gu Lu's Blog
作者:Gu Lu(顾露)
链接:http://gulu-dev.com/post/2016-02-07-lvalue-rvalue(点击尾部阅读原文前往)
问题:C++左值和右值区别
问题:关于C++左值和右值区别有没有什么简单明了的规则可以一眼辨别?
看了一下现有的答案,讲概念和理论的多,谈可操作性的少。我来说两个办法吧,不过都不是俺原创的。
来自 Scott Meyers 的方法
判断表达式是否是左值,有一个简单的办法,就是看看能否取它的地址,能取地址的就是左值。
A useful heuristic to determine whether an expression is an lvalue is to ask if you can take its address. If you can, it typically is. If you can’t, it’s usually an rvalue. A nice feature of this heuristic is that it helps you remember that the type of an expression is independent of whether the expression is an lvalue or an rvalue.
-- "Effective Modern C++", Introduction - Terminology and Conventions, Scott Meyers
来自 Joseph Mansfield 的方法
理解下面的几句话就可以了,顺带也清楚地表达了 std::move 和 std::forward 的区别和联系
左值可看作是“对象”,右值可看作是“值” (Lvalues represent objects and rvalues represent values)
左值到右值的转换可看做“读出对象的值” (Lvalue-to-rvalue conversion represents reading the value of an object)
std::move 允许把任何表达式以“值”的方式处理 (allows you to treat any expression as though it represents a value)
std::forward 允许在处理的同时,保留表达式为“对象”还是“值”的特性 (allows you to preserve whether an expression represented an object or a value)
那么这里的“对象” (object) 和 “值” (value) 是什么意思呢?任何一个有价值的 C++ 程序都是如此:a) 反复地操作各种类型的对象 b) 这些对象在运行时创建在明确的内存范围内 c) 这些对象内存储着值。 (Every useful C++ program revolves around the manipulation of objects, which are regions of memory created at runtime in which we store values.)
这一句话的解释实际上就指向了上面的第一条方法——只有特定的内存区域才可以被取地址。
举个栗子
先定义一个变量,
int foo;
此时,
表达式 foo 是一个左值,可以取地址 (&foo) (方法一),foo 本身是一个拥有明确内存范围的对象 (方法二)
表达式 foo + 5 是一个右值,无法取地址 (&(foo + 5)) (方法一),是一个需要被存储到对象里的值 (方法二)
关于第二种方法,更详细的讨论可见下面 Joseph Mansfield 的文章。此文行文流畅,对理解 lvalue/rvalue/move/forward 很有帮助。
(Joseph Mansfield) The lvalue/rvalue metaphor http://josephmansfield.uk/articles/lvalue-rvalue-metaphor.html
●本文编号1997,以后想阅读这篇文章直接输入1997即可。
●本文分类“C++”,搜索分类名可以获得相关文章。
●输入m可以获取到文章目录
Linux学习↓↓↓
C/C++↓↓↓
更多推荐《15个技术类公众微信》
涵盖:程序人生、算法与数据结构、黑客技术与网络安全、大数据技术、前端开发、Java、Python、Web开发、安卓开发、iOS开发、C/C++、.NET、Linux、数据库、运维等。