在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. Libevent官方代码样例学习(二)

    连接监听器: 接收TCP连接请求 evconnlistener机制用于监听并接受TCP连接请求. 这些方法在event2/listener.h中声明, 在Libevent 2.0.2-alpha之后的 ...

  2. 微信整合的时候 出现这个“redirect_uri 参数错误”

    这是因为你在 微信的 管理中心 / 应用详情 中的授权回调域 只需要写域名就可以了 比如www.xxxxx.com 不需要具体某个页面

  3. 实现外卖选餐时两级 tableView 联动效果

    最近实现了下饿了么中选餐时两级tableView联动效果,先上效果图,大家感受一下: 下面说下具体实现步骤: 首先分解一下,实现这个需求主要是两点,一是点击左边tableView,同时滚动右边tabl ...

  4. 【LeetCode】235. Lowest Common Ancestor of a Binary Search Tree (2 solutions)

    Lowest Common Ancestor of a Binary Search Tree Given a binary search tree (BST), find the lowest com ...

  5. 如果没有 Android 世界会是什么样子?

    2005年谷歌从安迪·鲁宾(Andy Rubin)手中收购Android系统,起初安迪·鲁宾(Andy Rubin)只是想为数码相机开发出一个更为先进的系统,所以有了 Android.但是智能手机行业 ...

  6. Git 别名(分布式版本控制系统)

    1.Git 别名 Git 并不会在你输入部分命令时自动推断出你想要的命令.如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名.这里有一些例子你 ...

  7. 面试求职中你需要了解的Java面向对象

    从毕业到现在,笔试过好多场 也面了好多场, 一直想写一些东西给找工作的朋友,这篇文章结合个人经历讲解面试中的面向对象.里边有些实例个人以面试题的形式写出来,从程序角度去b帮助大家了解学习,最后希望大家 ...

  8. TensorFlow 中的 tf.train.exponential_decay() 指数衰减法

    exponential_decay(learning_rate, global_step, decay_steps, decay_rate, staircase=False, name=None) 使 ...

  9. Lighttpd1.4.20源代码分析 笔记 状态机之错误处理和连接关闭

    这里所说的错误有两种: 1.http协议规定的错误,如404错误. 2.server执行过程中的错误.如write错误. 对于http协议规定的错误,这里的"错误"是针对clien ...

  10. com.mysql.jdbc.PacketTooBigException: Packet for query is too large (1169 > 1024)

    ### Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (1169 > 1024). You ...