前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >谈一谈 C++ 中的值的类型

谈一谈 C++ 中的值的类型

作者头像
ACM算法日常
发布2021-06-16 16:03:33
6300
发布2021-06-16 16:03:33
举报
文章被收录于专栏:ACM算法日常

C++98

历史上,我们把值分为两类,左值 ( lvalue ) 和右值 ( rvalue )。

右值,就是只能在等号右边的值,比如字面量。

左值,就是在等号左边出现的值,当然在等号右边也能出现。

比如

代码语言:javascript
复制
 a = 1; // a 是左值, 1 是右值
// 这个 1 被称作字面量

但是这样的分类方法,在遇到 const int 这样的类型时,就发现一个 const int 既不能分为左值,也不能分类为右值。(有且只有初始化时才能在等号左边出现)

所以在 C 中,左值,就是表示了一个“对象”(object) 的值,比如一个变量,一个指针等等。在 C++98 中,还把函数变成了左值。

左值的特点就是,可以绑定上左值引用。如果要引用一个右值,那引用必须是一个常引用。

代码语言:javascript
复制
int a = 100; // a 是一个左值
int &b = a; // b 是一个左值引用, 对 b 操作任何事情完全就是对 a 操作

C++11

在 C++11 中引入了一种新的语义——移动语义。具体地说,就是可以移动构造,还有移动赋值。

移动语义有点像“废物利用”一样。如果采用了移动构造,你就可以把自己身上的数据移动给新的成员,避免了不必要的数据复制。比如要移动几千个 std::string 类型的成员,C++98 中只能够复制一份再删除一份,而 C++11 中,就可以改一下 std::string 内部指针的位置,很方便。

但是要注意,只有废物才能被利用,我们给这类“废物”一个名字,就叫 xvalue,x 的意思是“将要过期的”(expiring)。原来的右值 rvalue 中细分成为了“纯右值” prvalue (pure rvalue)

所以在 C++11 中,有了三种数据类型:

lvalue

xvalue

prvalue

其中 xvalue 和 prvalue 统称 rvalue;而 lvalue 和 xvalue 统称 glvalue.


我们举一些例子。

prvalue:

字面量(除了字符串)

像 a++ 这样内置的后自增表达式(返回一个临时对象)

像 a+b 这样内置的运算、逻辑运算等

““返回一个非引用类型”的函数”的返回值

强制转换成了非引用类型

lambda 表达式

等等,更具体的分类可以看拓展阅读。

xvalue:

““返回一个右值引用”的函数”的返回值。比如 std::move(x)

强制转换了右值引用

也就是说,通过使用 std::move(x) 就可以把 x 的类型变成 xvalue,就可以调用移动构造函数了(如果实现了这个函数)。

(小提示:不要写出 return std::move(x); 这种语句,写 return x; 就行,不然会妨碍编译器优化。参考这里)


进一步,我们可以抽象出来这两个判断法则:

准则 1:能不能分辨两个表达式指的是同一个物体。比如我们可以通过比较地址。

准则 2:能不能使用移动语义。比如看看能不能用调用移动构造函数。

都满足,那就是 xvalue

满足 1 不满足 2,就是 lvalue

满足 2 不满足 1,就是 prvalue

满足 1 就统称为 glvalue,满足 2 的统称为 rvalue

分成这么多类,在绑定引用的时候就起了作用。比如不同的函数重载,一个 xvalue 优先会找右值引用,其次可能是常量左值的引用,这样就可以正确的发挥移动语义的作用了。

C++17

分类和 C++11 是一样的,但是语义上更加明确了。

glvalues:有自己地址的长寿对象

prvalues:为了初始化而用的短命对象

xvalue:资源已经不需要了,而且可以再利用的长寿对象

C++17 还引入了一些新的语法规定,有时候一个 prvalue 还可以 materialization 成 xvalue。当然,这些都不用太关心,写出问题了再说。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ACM算法日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C++98
  • C++11
  • C++17
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档