(2)左右值初探与auto类型说明符
这篇文章的起因是下面这两段代码,出自《C++ primer 5th》中文版P62页:
auto &h =42;//错误,不能为非常量引用绑定字面值
const auto &j =42;//正确,可以为常量引用绑定字面值
一开始看到auto时,我认为不存在错误的auto语句,因为auto就是根据右值类型来匹配一个适当的类型给左值~
结果这里居然错了!我很诧异,仔细看了看是const引起的,那么问题来了,为什么必须要加const才能识别42是一个const int&?
百度了一下,找到一个知乎的回答:
https://www.zhihu.com/question/36052573?utm_source=qq&utm_medium=social
感觉里面的问题描述和我想的一样,回答里说的却没有我想要的答案:为什么必须是const引用才能绑定字面值?有什么原因么?
我又去stack overflow提问,因为英文太差,问题描述不能很好的写出来:
https://stackoverflow.com/questions/46461946/cannot-bind-a-plain-reference-to-a-literal/46464445#46464445
误打误撞,又纠正了我一些概念上的问题,接下来我来总结一下。有些东西后面学到了才用到,我会点到即止,留下问题的可能答案以后看。
首先是文章开头那两段代码,为什么第一段错第二段对?
这里要明确几个概念:
(1)编译器先判断右值的类型,再决定左值的类型,而不是先定义左值的类型再进行绑定的操作......
(2)const 引用可以绑定字面值,而且auto引用和指针变量在绑定或赋值操作时是保留底层const属性的,而一般情况下是忽略顶层const属性,才需要人为添加const来声明顶层const属性。
(1、2改动自楼上第一个知乎答案里的问题描述)
(3)auto不能推断const,其默认只保留顶层const(这里和2有雷同,但为了完整我还是写出来了);非常量左值引用不能绑定到纯右值上。
(3是上面stack overflow中问题的回答理解,截图见下面)
这里补几个专业词汇:
pure rvalue=prvalue=纯右值 lvalue=left value=左值 rvalue=right value=右值
这三者有什么区别的?我觉得这个问题里很多回答说的很好:
https://www.zhihu.com/question/39846131/answer/85277628
简单的总结,就是有地址的就是左值,没有就是右值,至于里面提到的纯右值、右值引用概念,现在没必要深究,先放着,以后学到了再说,可以参考的文章有:
http://blog.csdn.net/ylbs110/article/details/51106164(我也不知道这篇文章质量如何,以后用到再说)
最后,再重新强调几个东西,基本数据类型、限定符、声明符列表是不一样的东西!int、double等是基本数据类型,const是限定符,声明符列表包括名字和修饰符,名字就是对象名字,修饰符有*和&(目前学到的只有这两个),而auto是类型说明符,换句话说,他只能表示或者替代基本数据类型!这也是为什么const我们要自己视情况加,auto并不能帮我们确定的原因————auto是一个类型说明符,其只能代替基本类型的位置,不能代替限定符const和类型修饰符&、*之流。
好了,准备工作都弄好了,现在可以试着解释上面的问题了。
首先是第一段代码。
auto
&h =42;//错误,不能为非常量引用绑定字面值
这段代码执行流程是这样的:
编译器会先判断右值的类型:“42”是一个int的字面值。
字面值里只有char类才有地址,其余都是右值!(左值是等号两边都可以放的,右值只能放等号右边,有地址的才是左值,否则是右值,姑且这样认为先),所以,这里的42是一个int型的右值。
编译器判断出这是一个int后,auto就等价于int了(注意,没有*没有&没有const,就只是等价于一个基础数据类型)
也就是说上面那段等价于:
Int &h =42;
这是一个绑定int型的引用,而规定是引用不能绑定一个纯右值,所以这里错了————我也不知道为什么,这里似乎牵扯到生命周期、纯右值,没学到,以后再说,可以参考的文章有:
https://stackoverflow.com/questions/39718268/why-do-const-references-extend-the-lifetime-of-rvalues
明白了这段代码哪里错,就能理解文章开头的第二段代码为什么对了——先死记吧,以后再说。
至此这个疑问就告一段落了,最后说一说这次查资料中自己纠正的一个错误概念:
等号两边的类型是一样的否则怎么能赋值呢。
明白上面这句话是错的,源自于上面我在stack overflow中提问的一个回答:
最后,我想强调一下auto定义的变量必须有初始值,而这正是有了他还要再有一个decltype类型指示符的原因。
有了auto是不是不需要显示声明类型了?————见:https://www.zhihu.com/question/35517805/answer/63304992
这个解释没看懂,以后再看
(2)左右值初探与auto类型说明符的更多相关文章
- auto类型说明符的注意事项
1.auto类型说明符,是C++11标准下的,它能让编译器自行判断表达式的类型. 2.auto也能在一条语句上声明多个变量,但是,该语句上的多个变量的类型,必须一致. 3.编译器推断出来auto类型可 ...
- C++11 auto类型说明符的使用
编程的时候常常需要把表达式的值赋给变量,这就要求在声明变量的时候清楚地知道表达式的类型.然而做到这一点很难,有时候根本做不到.为了解决这个问题.C++11新标准引入了auto类型说明符,用它就 能让编 ...
- C++ auto类型说明符
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50864612 编程时常常需要把表达式的 ...
- auto类型说明符
auto让编译器通过出初始值来推算变量的类型,显然,auto定义的变量必须有初始值: //由val1和val2相加的结果可以推断出item的类型 auto item = val1 + val2;//i ...
- C++通过迭代修改字符串本身(auto类型说明符)
以字符串这种支持 for (declaration : expression) statement 这样for语句迭代的数据结构为例,我们看看auto关键字在类型推断中的作用. string s = ...
- C++ decltype类型说明符(尾置返回类型使用)
转自https://blog.csdn.net/yhl_leo/article/details/50865552 1 基本语法 decltype 类型说明符生成指定表达式的类型.在此过程中,编译器分析 ...
- C++ decltype类型说明符
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50865552 1 基本语法 declt ...
- Effective Modern C++翻译(3)-条款2:明白auto类型推导
条款2 明白auto类型推导 如果你已经读完了条款1中有关模板类型推导的内容,那么你几乎已经知道了所有关于auto类型推导的事情,因为除了一个古怪的例外,auto的类型推导规则和模板的类型推导规则是一 ...
- 现代C++之理解auto类型推断
理解auto类型推断 上一篇帖子中讲述了模板类型推断,我们知道auto的实现原理是基于模板类型推断的,回顾一下模板类型推断: template <typename T> void f(Pa ...
随机推荐
- [52ABP系列] - 001、SPA免费项目模版搭建教程
前言 这个项目是基于 ABP ASPNetCore 免费版,整合 NG-Alian 和 NG-Zorro 的项目,所以比较适合熟悉 ABP 和 Angular2+ 的开发人员, 如果你是新手,学习的话 ...
- Android Studio 1.x 使用问题汇总
Android Studio是谷歌于13年I/O大会推出的Android开发环境,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提供了集成的Androi ...
- 【DataStructure】Charming usage of Set in the java
In an attempt to remove duplicate elements from list, I go to the lengths to take advantage of meth ...
- ios网络学习------11 原生API文件上传之断点续传思路
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVhbmcyMDA5MzAzNTEz/font/5a6L5L2T/fontsize/400/fill/I0 ...
- IOS View编程指南笔记
我们所示程序 对于一切IOS APP来说.我们看的的内容,都是UIView所呈现的. UIView如场景,UIWindow如舞台.UIView粉墨登场在UIWindow这个舞台上,使我们看到丰富多彩的 ...
- poj 3233(矩阵高速幂)
题目链接:http://poj.org/problem?id=3233. 题意:给出一个公式求这个式子模m的解: 分析:本题就是给的矩阵,所以非常显然是矩阵高速幂,但有一点.本题k的值非常大.所以要用 ...
- SpringMVC导出Excel
import java.math.BigDecimal; import java.net.URLEncoder; import java.text.SimpleDateFormat; import j ...
- 自己定义ViewGroup控件(一)----->流式布局进阶(一)
main.xml <? xml version="1.0" encoding="utf-8"?> <com.example.SimpleLay ...
- Java生成带logo 的二维码
这个工具类主要实现了两点功能: 1. 生成任意文链接的二维码. 2. 在二维码的中间加入图像. 主要实现步骤: 第一步: 导入QR二维码3.0 版本的core包和一张jpg图片(logo). core ...
- my.os.ClickThisWindow.ClickThisPoint.py
my.os.ClickThisWindow.ClickThisPoint.py