c++11 auto类型推导的使用建议和注意事项

概述:

首先c++是强类型语言,也就是在定义变量的时候必须指定具体的类型。

像我们常用的int,float,char等等都是类型,auto关键字原本的意思是说明某个变量是自动变量,c++11提升了它的功能。

在c++11之后,我们可以使用auto来进行类型推导。

auto var1 = 1;     // int 
auto var2 = 1L;    // long
auto var3 = 1LL;   // long long
auto var4 = 4.2f;  // float
auto var5 = 4.2;   // double
auto var6 = 'a';   // char

auto stu  = Student();      //  Student   自定以类型

上面,我们使用auto自动推导出了各变量的类型,我们不需要自己手动去写变量的类型,auto就可以根据后面的数据推断出变量的类型。

其实,auto用起来很方便,它可以让我们不去使用具体的类型,但是滥用auto并不好。 

 auto使用的注意事项

  • auto相当于一个占位符,使用auto必须同时对相应的数据进行初始化
  •  auto无法推断出引用和const
    const int a = 10;
    auto b = a;             // 此时auto推断出的类型为int,但是a是const int 
    b = 10;                   // 我们可以被允许修改b中的值

    int &a1 = a;   
    auto b1 = a1;        // 此时auto推出的类型为int, 但是a是 int&

所以,如果我们使用auto,并且用const和&修饰变量:   const auto & b1  = a1; 

  • auto不能推断数组类型
    auto a[3] = {1,2,3};         // 这样写是错误的

  • auto不能用于模板类型推断
    vector<int> v1;
    vector<auto> v2 = v1;  

  • auto不能用于函数形参

  • auto不能用于类内部成员变量的推导

     
  • 不能使用auto推导虚函数的函数返回值

  

auto的使用建议 

建议:   
1.  遇到类型较长的类型的情况
2.  遇到无法得知具体是什么类型的情况

虽然auto很方便,可以帮助自动推导类型,但是使用它有好有坏。 

比如:  

std::string func() {
    return std::string();
}

main:
auto ret = func();                 // 这里使用auto自动推导出函数返回的类型。为string
std::cout << ret.size() << std::endl;   

这是当我们对函数进行修改之后,其返回了char*类型
char *func() {
    return std::string();
}


好处:   
因为函数的返回值类型变量,那么用于接受这个返回值的变量的类型也需要改变,但是我们使用了auto,我们就不需要自己去修改它的类型。当func的返回值改变之后auto会自动推导出来。   --   这显然很方便,我们不需要修改源代码。

坏处:
1. 函数func返回了string类型,然后我们使用返回值去调用string内部的函数size,但是当函数进行修改之后,auto推导出来的类型为char*,很显然char*根本没有那个函数,所以程序会报错。 --   如果你代码中多处用到返回值中的函数,会导致程序问题

2. 使用auto之后可读性变差了,因为如果你直接写std::string或者char*,阅读者很容易就知道这个变量的类型,以及返回值的类型。

如果你使用auto:  你得把光标放到变量上,vs的智能提示才可知道变量的类型,更或者我们得查看函数的声明或者定义才可以知道变量的类型。  --  这样很不直观

所以在正常的情况下是不建议使用auto关键字的。

那么应该什么时候使用?

看下面的情况:  

std::map<std::string, std::string> m1;
m1.emplace("好好","学习");

// 使用迭代器
for (std::map<std::string, std::string>::const_iterator it = m1.cbegin(); it != m1.cend(); it++) {

}

下面,我们是使用了迭代器去遍历我们的容器map的,你会发现使用迭代器类型的时候它的类型很长,显得代码很臃肿,这时候我们就可以使用auto关键字使得代码更加的整洁。
 

使用auto的for循环:

for (auto it = m1.cbegin(); it != m1.cend(); it++) {

}

很显然,这种写法更加的整洁。

当然了,这只是一种写法,你也可以使用c++11新增的for循环来遍历容器。

 
所以,我们应该在类型比较长的时候,或者我们不知道使用的是什么类型的时候可以选择使用auto。


其实,对于长类型你可以拥有另外一种选择:

using const_iterator = std::map<std::string, std::string>::const_iterator;
typedef std::map<std::string, std::string>::const_iterator const_iterator;


// 使用迭代器
for (const_iterator it = m1.cbegin(); it != m1.cend(); it++) {

}
 

我们使用using和typedef(c++11之前使用),用一个较短的类型名替换了长度较长的类型名。

(对于长类型,使用auto还是给类型定义别名的方式,看自己的选择)

c++14新增的auto关键字功能(函数返回值)

1. 在c++14之后,我们可以使用auto来推导出函数的返回值类型(根据函数的返回值) -- 可用于函数模板的返回值


auto func1(){         // auto会推断出此函数返回int类型。
    return 1;
}

auto func(){          // 返回值为void

}

注意: 
这种场景下,如果函数有多个分支需要返回值,那么需要保证多个分支的返回值应该是一样的。比如:

auto func() {
    bool ret = true;

    if (!ret)
        return 1.1;
    else
        return 1;       // error,因为两个分支的返回类型不同
}




2. c++14之后我们还可以将auto使用在函数声明的返回值中
比如: 
auto func2();                // 函数func2的声明, auto会根据函数的定义推断出其返回值

但是,注意其函数定义的返回值也必须为auto,否则会被认为是函数的重载形式。

所以func2的定义为:                      // 最后返回值类型推断为double
auto func2(){
    return 1.0;                     
}

相关推荐

  1. c++11 auto类型推导使用建议注意事项

    2024-05-26 04:04:36       39 阅读
  2. go 基础概念-变量类型使用注意事项

    2024-05-26 04:04:36       41 阅读
  3. C++使用模板注意事项

    2024-05-26 04:04:36       44 阅读
  4. Docker EntrypointCMD同时使用注意事项

    2024-05-26 04:04:36       38 阅读
  5. 详解QString类使用注意事项

    2024-05-26 04:04:36       46 阅读
  6. 建设工程司法鉴定注意事项

    2024-05-26 04:04:36       43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-26 04:04:36       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-26 04:04:36       101 阅读
  3. 在Django里面运行非项目文件

    2024-05-26 04:04:36       82 阅读
  4. Python语言-面向对象

    2024-05-26 04:04:36       91 阅读

热门阅读

  1. HTML5

    2024-05-26 04:04:36       35 阅读
  2. Android-okhttp调接口传参简单举例

    2024-05-26 04:04:36       33 阅读
  3. qt里的QPieSeries饼图

    2024-05-26 04:04:36       31 阅读
  4. Python 点云裁剪

    2024-05-26 04:04:36       37 阅读
  5. 汇编实现流水灯

    2024-05-26 04:04:36       33 阅读
  6. 入门Kotlin的学习之路经验总结

    2024-05-26 04:04:36       34 阅读
  7. icloud如何高效利用

    2024-05-26 04:04:36       31 阅读
  8. NDIS小端口驱动(六)

    2024-05-26 04:04:36       27 阅读
  9. unity 常用工具和代码

    2024-05-26 04:04:36       32 阅读
  10. docker image prune -f 命令什么用途

    2024-05-26 04:04:36       32 阅读
  11. dirsearch指令大全

    2024-05-26 04:04:36       41 阅读