C++11 类型推导auto
在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的更多相关文章
- C++11 - 类型推导auto关键字
在C++11中,auto关键字被作为类型自动类型推导关键字 (1)基本用法 C++98:类型 变量名 = 初值; int i = 10; C++11:auto 变量名 = 初值; auto i ...
- C++11类型推导
[C++11类型推导] auto 关键字.这会依据该初始化子(initializer)的具体类型产生参数: 除此之外,decltype 能够被用来在编译期决定一个表示式的类型. 参考:http://z ...
- C++11 自动推导auto
C++11 自动推导auto C++11中引入的auto主要有两种用途:自动类型推导和返回值占位. auto在C++98中的标识临时变量的语义,由于使用极少且多余,在C++11中已被删除.前后两个标准 ...
- C++11 类型推导decltype
我们之前使用的typeid运算符来查询一个变量的类型,这种类型查询在运行时进行.RTTI机制为每一个类型产生一个type_info类型的数据,而typeid查询返回的变量相应type_info数据,通 ...
- C++ 11 学习1:类型自动推导 auto和decltype
Cocos 3.x 用了大量的C++ 11 的东西,所以作为一个C++忠实粉丝,有必要对C++ 11进行一个系统的学习. 使用C++11之前,一定要注意自己使用的编译器对C++11的支持情况,有些编译 ...
- c++11——auto,decltype类型推导
c++11中引入了auto和decltype关键字实现类型推导,通过这两个关键字不仅能够方便的获取复杂的类型,而且还能简化书写,提高编码效率. auto和decltype的类型推导都是编译器在 ...
- C++11 图说VS2013下的引用叠加规则和模板参数类型推导规则
背景: 最近在学习C++STL,出于偶然,在C++Reference上看到了vector下的emplace_back函数,不想由此引发了一系列的“探索”,于是就有了现在这篇博文. 前言: ...
- Effective Modern C++翻译(3)-条款2:明白auto类型推导
条款2 明白auto类型推导 如果你已经读完了条款1中有关模板类型推导的内容,那么你几乎已经知道了所有关于auto类型推导的事情,因为除了一个古怪的例外,auto的类型推导规则和模板的类型推导规则是一 ...
- 类型推导:函数模板与auto
1.从函数模板谈起 函数模板的类型推导机制是在c++98时代就有的,auto的类型推导机制与其基本一致,所以先理解函数模板类型推导. 函数模板可以用如下代码框架表示: #template<typ ...
随机推荐
- Ubuntu18.04下的音频录制和编辑软件Ardour及QjackCtl(jackd gui)
Ardour 是一个Linux和OSX下的多音轨录制和数字音频编辑软件. 需要配合ALSA或者JACK总线使用. 快速入门 http://brunoruviaro.github.io/ardour4- ...
- 解决 Class not found和Base table or view not found: 1051 问题
1.解决class not found的方法: 如果你用的是homestead虚拟机,那么,你要到虚拟机下执行: composer dump-autoload 2.解决Base table or vi ...
- js实现放大缩小页面
<script type="text/JavaScript"> var size = 1.0; function zoomout() { size = size + 0 ...
- JavaScript原生对象及扩展
来源于 https://segmentfault.com/a/1190000002634958 内置对象与原生对象 内置(Build-in)对象与原生(Naitve)对象的区别在于:前者总是在引擎初始 ...
- keras中的loss、optimizer、metrics
用keras搭好模型架构之后的下一步,就是执行编译操作.在编译时,经常需要指定三个参数 loss optimizer metrics 这三个参数有两类选择: 使用字符串 使用标识符,如keras.lo ...
- iOS 中的静态库与动态库,区别、制作和使用
如果我们有些功能要给别人用,但是又不想公开代码实现,比如高德地图.第三方登录分享等等,这时候我们就要打包成库了.库分静态库和动态库两种: 静态库:以.a 和 .framework为文件后缀名.动态库: ...
- 初步了解pandas(学习笔记)
1 pandas简介 pandas 是一种列存数据分析 API.它是用于处理和分析输入数据的强大工具,很多机器学习框架都支持将 pandas 数据结构作为输入. 虽然全方位介绍 pandas API ...
- SimpleAdapter真不简单!
作为一名编程初学者,我总是认为自己什么都不会,什么都不行,就算实现了文档指定的功能,我永远都是觉得自己写过的代码实在是太烂了,它只是恰巧能够运行而已!它只是在运行的时候恰巧没有发现错误而已!!一直都是 ...
- js scrollIntoView 滚动到元素可视区域
老是忘记这个函数名,记录一下啊 // 滚动到可视区域 document.querySelector(".loading").scrollIntoView()
- ELK日志相关
转: Logstash 讲解与实战应用 原创qw871122016-08-20 16:06:07评论(1)40217人阅读 一.Logstash 介绍 Logstash 是一款强大的数据处理工具,它可 ...