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;
}
原文地址:https://www.cnblogs.com/QingYiShouJiuRen/p/11382610.html