zoukankan      html  css  js  c++  java
  • C++11新特性之auto关键字的使用

    一.auto关键字简介

    auto这个关键字并不是一个全新的关键字,在旧标准中,它代表的是“具有自动存储期的局部变量”;但是它在这方面并没有起到很大的作用,比如:auto int i = 10 与int i = 10是等价的, 在旧标准中我们很少会用到auto关键字,因为非静态变量在默认的情况下本就是“具有自动存储期的”。

    考虑到在旧标准中auto关键字用的很少。在C++11新特性中,auto关键字不在表示存储类型指示符,而是把它改成了一个类型指示符,用来提示编译器对此类型变量做类型的自动推导。

    二.auto的推导规则

    下述示例需要在支持C++11新特性的编译器中执行,否则会出现编译错误

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int x = 10;
        auto *a = &x;       //auto被推导为int
        auto b = &x;        //auto被推导为int*
        auto &c = x;        //auto被推导为int
        auto d = c;         //auto被推导为int
        
        const auto e = x;   //auto被推导为int
        auto f = e;         //auto被推导为int
            
        const auto& g = x;  //auto被推导为int
        auto& h = g;        //auto被推导为int
    
        return 0;
    }

    A.d的推导结果说明了当表达式是一个引用类型时,auto会把引用类型抛弃,直接推导成原始类型int;

    B.f的推导结果说明了当表达式带有const属性时,auto会把const属性抛弃掉,直接推导成int类型;

    C.g和h的推导说明了当auto和引用(换成指针在这里也将得到同样的结果)结合时,auto的推导将保留变量的const属性

    下面是上述推导A的验证实例

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int x = 10;
        const auto z = x;
        auto y = z;
        y = 10;
        cout << y << endl;
    
        const int a = 10;
        a = 20;
        cout << a << endl;
    
        return 0;
    }

    在C++中,const int a = 10;初始化完成后,在为a赋值为20,编译器便会报错。如下所示:

    a现在只是一个可读变量,不可在更改它的初始值;所以说,如果上述y变量类型推导为const int,再为y赋值的话,在编译时会报出同样的错误,但在编译时并未出现上述错误,那就说明在进行类型推导时,把const属性给抛弃掉了,只保留了一个原始类型int.

    下面是上述推导C的验证实例

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int x = 10;
        const auto& z = x;
        z = 20;
        cout << z << endl;
    
        return 0;
    }

    编译后会出现如下错误:

    可以看出z只是一个只读引用,即const int &类型,不能再为其赋值。

    从以上示例可以总结出下面两条规则

    (1).当不声明为指针或引用时,auto的推导结果和初始化表达式抛弃引用和cv限定符(const和volatile限定符的统称)。

    (2).当声明为指针或引用时,auto的推导结果将保持初始化表达式的cv属性。

    三.auto的使用范围

    auto关键字不是说在任何地方都能适用的;

    (1).不能作为函数的形参

    (2).不能用于非静态成员变量

    (3).auto无法定义数组

    (4).auto无法推导出模板参数

    示例如下:

    #include <iostream>
    #include <list>
    using namespace std;
    
    struct MyStruct
    {
        auto nValue = 0;  //错误: 非静态的成员变量
        static const auto value = 10;
    };
    
    void MyPrintf(auto i) //警告:在参数声明中使用“auto”只能用-STD= C++1Y或-STD= GNU+1Y:
    {
        cout << i << endl;
    }
    
    int main()
    {
        auto array[10] = {0};   //错误:无法定义数组
        list<auto> MyList;      //错误:无法推导出模板的参数类型
        auto i = 10;
        MyPrintf(i);
        return 0;
    }

    那么在什么时候使用auto关键字呢?当变量定义过于冗长时,可以考虑使用auto关键字代替;比如说C++去遍历一个stl容器,迭代器定义时比较累赘,换成auto关键之后是不是瞬间清爽了不少。

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    int main()
    {
        vector<int> MyVector;
        //插入数据
        for(int i = 0; i < 10; i++)
        {
            MyVector.push_back(i);
        }
        //旧特性中遍历数据
        vector<int>::iterator it = MyVector.begin();
        for(; it != MyVector.end(); it++)
        {
            cout << *it <<",";
        }
        cout << endl;
        //新特性中遍历数据
        auto MyIt = MyVector.begin();
        for(; MyIt != MyVector.end(); MyIt++)
        {
            cout << *MyIt << ",";
        }
        return 0;
    }
  • 相关阅读:
    Python连接redis时要注意的点
    Python SQLAlchemy多对多外键关联时表结构
    SQLAlchemy中解决数据库访问时出现的Incorrect string value: xxx at row 484
    HDFS集群数据不均衡处理
    elasticsearch数据过期删除处理
    docker使用技巧小记
    kubeadm部署kubernetes-1.12.0 HA集群-ipvs
    k8s全栈监控之metrics-server和prometheus
    k8s小工具
    k8s集群之上游dns--dnsmasq,统一管理kubernetes的dns解析
  • 原文地址:https://www.cnblogs.com/QingYiShouJiuRen/p/11382610.html
Copyright © 2011-2022 走看看