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为 int
auto serven_6 = &serven_5;           // serven_6为 int*,所以推导auto为 int*
auto &serven_7 = serven_6;           // serven_7为 int&,所以推导auto为int
auto 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被推导为int
auto serven_11 = serven_10;         // serven_11为 const int, auto被推导为int(const属性被抛弃)
const auto &serven_12 = serven_9;   // serven_12为 const int&类型,auto被推导为int
auto &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,那么编译器不知道你究竟要干嘛,直接给你报错算了,例如:

template<typename T>
class A{
  
};
​
int main(){
  A<int> C1;
  A<auto> C2 = C1;            // 编译器直接给你报错
  return 0;
}


四、auto的应用

1、使用auto来定义迭代器

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

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

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

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

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

2、auto用于泛型编程

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

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

运行结果是:

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

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

运行结果:

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三贝勒文子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值