zoukankan      html  css  js  c++  java
  • (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

    这个解释没看懂,以后再看

    wuduojia
  • 相关阅读:
    通过HttpListener实现简单的Http服务
    WCF心跳判断服务端及客户端是否掉线并实现重连接
    NHibernate初学六之关联多对多关系
    NHibernate初学五之关联一对多关系
    EXTJS 4.2 资料 跨域的问题
    EXTJS 4.2 资料 控件之Grid 那些事
    EXTJS 3.0 资料 控件之 GridPanel属性与方法大全
    EXTJS 3.0 资料 控件之 Toolbar 两行的用法
    EXTJS 3.0 资料 控件之 combo 用法
    EXTJS 4.2 资料 控件之 Store 用法
  • 原文地址:https://www.cnblogs.com/wuduojia/p/7608597.html
Copyright © 2011-2022 走看看