> 文档中心 > C++11新特性之auto类型推导

C++11新特性之auto类型推导

        在C++11新特性出现之前,我们在定义变量的时候必须给定这个变量一个具体的类型,像int、char、double等等。

        今天小编要来给大家介绍在C++11新特性出现的一个类型推导auto,它主要是让编译器(解析器)自己来推导,这就是让我们在编写代码的时候更加方便,不用先去考虑这个变量究竟要设定为什么类型。

一、auto类型推导的语法和规则

        其实在C++11版本之前auto也是一个关键字,但是这个关键字主要是来表示我们定义的变量是否是自动存储的,也就是跟static一样,在定义变量类型之前加上这个关键字,但是加不加上感觉意义不大。

        然而,在C++11之后,auto关键字被赋予了新的功能,也就是用于类型推导,也就是说,使用了auto关键字以后,编译器会在编译期间自动推导出变量的类型,auto的语法为:

auto name = value;

        其中,name为变量的名字,value为变量的初始值。在编译期间,编译器会根据value的类型来推导name的类型,假设value为int类型,name就是int类型,auto会被int替代掉。在这里要注意:auto仅仅只是一个占位符,在编译期间会被真正的类型所替代。下面我们来看几个例子:

auto serven_1 = 1;auto serven_2 = 1.2;auto serven_p = & serven_1;auto serven_url = "https://www.baidu.com";

根据上面代码,在编译期间:

  • 因为1是int类型,所以serven_1会被推导为int类型,其中auto被推导为int;因为1.2是double类型,所以serven_2会被推导为double类型,其中auto被推导为double;

  • 因为&serven_1的结果是一个int*类型的指针,所以推导serven_p为int类型的指针,指向serven_1的地址,auto被推导为int*;

  • 因为“”包围起来的字符串是const char*类型, 所以推导变量serven_url的类型是const char*, 也就是一个常量指针。

auto定义多个变量:

int serven_3 = 2;auto *serven_q = &serven_3, serven_4 = 3;

        在代码的第二行中,我们可以看到了&serven_3的类型是一个int*,编译器会根据auto *serven_q推导出auto为int。后面的变量serven_4自然就是int类型了。值得注意的是,推导的时候不能有二义性,就是说不能写成下面的形式:

int serven_3 = 2;auto *serven_q = &serven_3, serven_4 = 12.5;      // 编译器会报错,因为不知道推导为int还是double

        另外,auto在定义变量的时候要立马初始化,因为auto在C++11中只是一个“占位符”,并非像int一样的真正的类型声明;

二、auto的复合用法

    auto除了可以独立使用,还可以和某些具体类型混合使用,这样的auto表示的就是半个类型,而不是完整的类型:

int serven_5 = 4;   auto *serven_p = &serven_5;          // serven_p为 int*, 所以推导auto为 intauto serven_6 = &serven_5;           // serven_6为 int*,所以推导auto为 int*auto &serven_7 = serven_6;           // serven_7为 int&,所以推导auto为intauto serven_8 = serven_7;            // serven_8为int, 所以推导auto为int 

    上面第五行代码中,serven_7本来是int&类型,但是auto却被推导为int类型,这表明了当=右边的表达式是一个引用类型时,auto会把引用抛弃,直接推导出它的原始类型

三、auto和const结合的用法

int serven_9 = 8;const auto serven_10 = serven_9;    // serven_10为 const int,auto被推导为intauto serven_11 = serven_10;         // serven_11为 const int, auto被推导为int(const属性被抛弃)const auto &serven_12 = serven_9;   // serven_12为 const int&类型,auto被推导为intauto &serven_13 = serven_12;        //serven_12为 const int&类型,auto被推导为const int 类型

auto和const结合的使用方法总结:

  • 当类型不为引用时,auto的推导结果将不保留表达式的const属性;

  • 当类型为引用时,auto的推导结果将保留表达式的const属性;

三、auto的限制

从前面知道auto在定义变量的时候是需要初始化的,所以:

1、auto定义变量时需要初始化;

2、auto不能在函数的参数中使用(因为函数参数是没有赋值的);

3、auto不能作用域类的非静态变量(即没有static关键字修饰的成员变量)中;

4、auto关键字不能定义数组;

5、auto关键字不能作用于模板参数,因为模板参数本来就是用来作为一个模板用的,具体的类型还未可知,我们如果使用了auto,那么编译器不知道你究竟要干嘛,直接给你报错算了,例如:

templateclass A{  };​int main(){  A C1;  A C2 = C1;     // 编译器直接给你报错  return 0;}

四、auto的应用

1、使用auto来定义迭代器

         我们在使用容器时,难免会通过迭代器来遍历容器,然而我们在定义迭代器的时候是这么写的:

vector result = {1,2,3};for(vector::iterator it = result.begin(); it != result.end(); it++){  cout<<*it<<" ";}

会不会觉得for里面的表达式太长了,可以利用auto写成下面的形式:

vector result = {1,2,3};for(auto it = result.begin(); it != result.end(); it++){  cout<<*it<<" ";}

也就是将vector::iterator 替换成auto,直接让编译器来帮我们推导这个it是啥玩意。

2、auto用于泛型编程

        auto的另外一个应用就是当我们不知道变量是什么类型,或者不希望指明具体类型的时候,比如泛型编程中,举个例子:

#include #include using namespace std;​class SERVEN_PAR{public:    static int Show(){ return 100;    }};​class SERVEN_CHI{public:    static char* Show(){ return "SERVEN_CHILD";    }};​templatevoid Func(){    T2 value = T1::Show();    cout<<value<<endl;}​int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);​    Func();    Func();​​    return a.exec();}​

运行结果是:

其实不使用auto的话也可以,可以使用模板参数来实现:

#include #include using namespace std;​class SERVEN_PAR{public:    static int Show(){ return 100;    }};​class SERVEN_CHI{public:    static char* Show(){ return "SERVEN_CHILD";    }};​templatevoid Func(){    auto value = T1::Show();    cout<<value<<endl;}​int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);​    Func();    Func();​​    return a.exec();}​

运行结果:

好看字体下载