在C++11之前,auto关键字用来指定存储期。在新标准中,它的功能变为类型推断。auto现在成了一个类型的占位符,通知编译器去根据初始化代码推断所声明变量的真实类型。
使用auto会拖慢c++效率吗?完全不会,因为在编译阶段编译器已经帮程序员推导好了变量的类型。
使用auto会拖累C++编译效率吗?完全不会,因为在auto出现之前C++需要先推导等号右侧表达式的类型,然后检查它与变量的类型是否可以转换(兼容转换、向下类型转换和自定义类型转换)。auto出现之后,C++在推导出等号右侧表达式的类型之后,直接指定给变量。

auto并非一种类型声明,而是类型声明时的占位符,编译器在编译时期会将auto替代为变量的实际类型。因此不能和typeid,sizeof一起使用。

1.使用auto通常意味着更短的代码(除非你所用类型是int,它会比auto少一个字母)

试想一下当你遍历STL容器时需要声明的那些迭代器(iterator),现在不需要去声明那些typedef就可以得到简洁的代码了。

std::map<std::string, std::vector<int>> map;
for(auto it = begin(map); it != end(map); ++it) {}

2.返回值占位符

auto不能用来声明函数的返回值,但如果函数有一个尾随的返回类型时,auto是可以出现在函数声明中返回值位置。这种情况下,auto并不是告诉编译器去推断返回类型,而是指引编译器去函数的末端寻找返回值类型。在下面这个例子中,函数的返回值类型就是operator+操作符作用在T1、T2类型变量上的返回值类型。

template <typename T1, typename T2>
auto compose(T1 t1, T2 t2) -> decltype(t1 + t2)
{
return t1+t2;
}
auto v = compose(, 3.14); // v's type is double

3.auto声明的变量必须初始化

int main()
{
auto m = ;
auto n{};
auto z = new auto(); auto a; //错误,未初始化
auto int b = ; //错误,auto不能和其它类型一起使用(C++98和C中可以)
auto c = new auto(); //错误,没有初始化
auto d = , e = 2.01; //错误,定义在一个auto序列的变量必须始终推导成同一类型 return ;
}

4.C++标准中规定auto可以与CV(const & volatile qualifiers)限制符一起使用,不过声明为auto的变量不能从其初始化表达式中带走CV限制符

从const变量推导或用auto接收从函数返回的const变量,会丢失const属性,除非显示声明为引用类型。

从引用变量推导或用auto接收从函数返回的引用变量,会丢失引用特性,除非显示声明为引用类型。

#include <iostream>
#include <typeinfo>
#include <vector> using namespace std; struct student
{
std::string name;
int age;
student(std::string name, int age)
: name(name)
, age(age)
{
std::cout << "constructor" << std::endl;
} student(const student& rhs)
{
std::cout << "copy constructor" << std::endl;
this->name = rhs.name;
this->age = rhs.age;
}
}; student& backRef(student& s)
{
return s;
} int main()
{
const auto var1 = ; //var1为const int
auto var2 = var1; //var1为int(除非var2声明为:auto& var2类型)
auto& var3 = var1; //var3为const int
var2 = ; //经过auto推导,var2变量已经丢失了const属性
//var3 = 5; //错误,const变量禁止修改 auto var4 = ;
auto& var5 = var4; //var5是var4的引用类型
var5 = ;
auto var6 = var5; //从var5中推导,只会获得变量类型,会丢失引用特性
var6 = ;
std::cout << "var4:" << var4 << std::endl;
std::cout << "var5:" << var5 << std::endl;
std::cout << "var6:" << var6 << std::endl; student stu1{"sanz", };
auto stu2 = stu1; auto stu3 = backRef(stu1); //函数返回引用类型,但实际会调用拷贝构造函数
stu3.age = ;
auto& stu4 = backRef(stu1); //显示添加引用后,还是stu1
stu4.age = ;
std::cout << stu1.age << std::endl;
std::cout << stu2.age << std::endl;
std::cout << stu3.age << std::endl;
std::cout << stu4.age << std::endl; return ;
}

auto也不是万能的,受制于语法的二义性,或者是实现的困难性,auto往往也有使用上的限制。

#include <iostream>
#include <typeinfo>
#include <vector> using namespace std; struct str
{
auto var = ; //1.a通过编译auto非静态成员变量,无法
}; void fun(auto x) //2.auto函数参数,无法通过编译
{
} int main()
{
int x[];
auto y = x;
auto z[] = x; //3.auto数组,无法通过编译 //auto模版参数,无法通过编译
vector<auto> v = {}; return ;
}

分析一下上述4中不能推导的情况:

1.对于函数fun来说,auto不能是其形参类型。由于其有默认参数,所以应该推导fun形参x的类型为int型。但事实无法符合大家的想象,如果程序员需要泛型的参数,还是求助与模版。

2.对于结构体或类来说,非静态成员变量的类型不能为auto。编译器阻止auto对结构体中的非静态成员进行推导,即使成员拥有初始值。

3.声明auto数组。x是一个数组,y类型是可以推导的,而声明auto z[3]这样的数字同样会被编译器禁止。

4.在实例化模版的时候使用auto作为模版参数,虽然读者认为这里一眼而知是int类型,但编译器却阻止了编译。

C++11 类型推导auto的更多相关文章

  1. C++11 - 类型推导auto关键字

    在C++11中,auto关键字被作为类型自动类型推导关键字 (1)基本用法 C++98:类型 变量名 = 初值;   int i = 10; C++11:auto 变量名 = 初值;  auto i ...

  2. C++11类型推导

    [C++11类型推导] auto 关键字.这会依据该初始化子(initializer)的具体类型产生参数: 除此之外,decltype 能够被用来在编译期决定一个表示式的类型. 参考:http://z ...

  3. C++11 自动推导auto

    C++11 自动推导auto C++11中引入的auto主要有两种用途:自动类型推导和返回值占位. auto在C++98中的标识临时变量的语义,由于使用极少且多余,在C++11中已被删除.前后两个标准 ...

  4. C++11 类型推导decltype

    我们之前使用的typeid运算符来查询一个变量的类型,这种类型查询在运行时进行.RTTI机制为每一个类型产生一个type_info类型的数据,而typeid查询返回的变量相应type_info数据,通 ...

  5. C++ 11 学习1:类型自动推导 auto和decltype

    Cocos 3.x 用了大量的C++ 11 的东西,所以作为一个C++忠实粉丝,有必要对C++ 11进行一个系统的学习. 使用C++11之前,一定要注意自己使用的编译器对C++11的支持情况,有些编译 ...

  6. c++11——auto,decltype类型推导

    c++11中引入了auto和decltype关键字实现类型推导,通过这两个关键字不仅能够方便的获取复杂的类型,而且还能简化书写,提高编码效率.     auto和decltype的类型推导都是编译器在 ...

  7. C++11 图说VS2013下的引用叠加规则和模板参数类型推导规则

    背景:    最近在学习C++STL,出于偶然,在C++Reference上看到了vector下的emplace_back函数,不想由此引发了一系列的“探索”,于是就有了现在这篇博文. 前言:     ...

  8. Effective Modern C++翻译(3)-条款2:明白auto类型推导

    条款2 明白auto类型推导 如果你已经读完了条款1中有关模板类型推导的内容,那么你几乎已经知道了所有关于auto类型推导的事情,因为除了一个古怪的例外,auto的类型推导规则和模板的类型推导规则是一 ...

  9. 类型推导:函数模板与auto

    1.从函数模板谈起 函数模板的类型推导机制是在c++98时代就有的,auto的类型推导机制与其基本一致,所以先理解函数模板类型推导. 函数模板可以用如下代码框架表示: #template<typ ...

随机推荐

  1. 比较MessageListActivity使用不同的layout

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  2. Dubbo整合SpringBoot

    目前的dubbo已支持和springboot集成,还是之前的例子,这次我们通过springboot容器来实现.借此了解一下基于springboot容器启动的dubbo的配置及使用. 1. 准备工作 创 ...

  3. std::string std::wstring 删除最后元素 得到最后元素

    std::string str = "abcdefg,"; std::cout << "last character:"<<str.ba ...

  4. Redis学习之路(002)- Ubuntu下redis开放端口

    Redis在ubuntu安装后默认是只有本地访问,需要别的ip访问我们需要修改redis的配置文件 1. dpkg -L redis-server 这命令我们可以看到redis的安装的文件在那些目录 ...

  5. WIFEXITED WEXITSTATUS WIFSIGNALED(转)

    wait的函数原型是: #include #include pid_t wait(int *status) 进 程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出 ...

  6. Javascript将html转成pdf,下载(html2canvas 和 jsPDF)

    最近碰到个需求,需要把当前页面生成pdf,并下载.弄了几天,自己整理整理,记录下来,我觉得应该会有人需要 :) 项目源码地址:https://github.com/linwalker/render-h ...

  7. 【HTML】网页中如何让DIV在网页滚动到特定位置时出现

    用js或者jquery比较好实现.但你要知道,滚动到哪个特定位置,例如滚动到一个标题h3那显示这个div,那么可以用jquery算这个h3距离网页顶部的距离:$("h3").off ...

  8. 【java】详解集合

    目录结构: contents structure [-] 集合概述 什么是集合 Collection和Map的区别 List和Set的区别 ArrayList和LinkedList的区别 HashSe ...

  9. Swift 类型转换

    1.类型转换 1.1 隐式类型转换 如 C 语言的类型转换 1.2 显式类型转换 Swift 语言是一种强类型语言,其整型的强制类型转换就是调用了参数类型对应的整形扩展构造方法,然后通过对应扩展构造方 ...

  10. web前端学习笔记-瀑布流的算法分析与代码实现

    瀑布流效果目前应用很广泛,像花瓣,新浪轻博,蘑菇街,美丽说等好多网站都有.也有好多支持该效果的前段框架,今天学习了一下这种效果的实现,不依赖插件,自己动手分析实现过程,为了便于叙述清楚,分析中的一些名 ...