c ++ auto 的使用
该文转自:https://www.cnblogs.com/KunLunSu/p/7861330.html
C++98 auto
早在C++98标准中就存在了auto关键字,那时的auto用于声明变量为自动变量,自动变量意为拥有自动的生命期,这是多余的,因为就算不使用auto声明,变量依旧拥有自动的生命期:
int a =10 ; //拥有自动生命期
auto int b = 20 ;//拥有自动生命期
static int c = 30 ;//延长了生命期
C++98中的auto多余且极少使用,C++11已经删除了这一用法,取而代之的是全新的auto:变量的自动类型推断。
C++11 auto
auto可以在声明变量的时候根据变量初始值的类型自动为此变量选择匹配的类型,类似的关键字还有decltype。举个例子:
int a = 10;
auto au_a = a;//自动类型推断,au_a为int类型
cout << typeid(au_a).name() << endl;
typeid运算符可以输出变量的类型。程序的运行结果输出了
int
这种用法就类似于C#中的var关键字。auto的自动类型推断发生在编译期,所以使用auto并不会造成程序运行时效率的降低。而是否会造成编译期的时间消耗,我认为是不会的,在未使用auto时,编译器也需要得知右操作数的类型,再与左操作数的类型进行比较,检查是否可以发生相应的转化,是否需要进行隐式类型转换。
auto的用法
上面举的这个例子很简单,在真正编程的时候也不建议这样来使用auto,直接写出变量的类型更加清晰易懂。下面列举auto关键字的正确用法。
用于代替冗长复杂、变量使用范围专一的变量声明。
想象一下在没有auto的时候,我们操作标准库时经常需要这样:
#include<string>
#include<vector>
int main()
{
std::vector<std::string> vs;
for (std::vector<std::string>::iterator i = vs.begin(); i != vs.end(); i++)
{
//...
}
}
这样看代码写代码实在烦得很。有人可能会说为何不直接使用using namespace std,这样代码可以短一点。实际上这不是该建议的方法(C++Primer对此有相关叙述)。使用auto能简化代码:
#include<string>
#include<vector>
int main()
{
std::vector<std::string> vs;
for (auto i = vs.begin(); i != vs.end(); i++)
{
//..
}
}
for循环中的i将在编译时自动推导其类型,而不用我们显式去定义那长长的一串。
在定义模板函数时,用于声明依赖模板参数的变量类型。
template <typename _Tx,typename _Ty>
void Multiply(_Tx x, _Ty y)
{
auto v = x*y;
std::cout << v;
}
若不使用auto变量来声明v,那这个函数就难定义啦,不到编译的时候,谁知道x*y的真正类型是什么呢?
模板函数依赖于模板参数的返回值
template <typename _Tx, typename _Ty>
auto multiply(_Tx x, _Ty y)->decltype(x*y)
{
return x*y;
}
当模板函数的返回值依赖于模板的参数时,我们依旧无法在编译代码前确定模板参数的类型,故也无从知道返回值的类型,这时我们可以使用auto。格式如上所示。
decltype操作符用于查询表达式的数据类型,也是C++11标准引入的新的运算符,其目的也是解决泛型编程中有些类型由模板参数决定,而难以表示它的问题。
auto在这里的作用也称为返回值占位,它只是为函数返回值占了一个位置,真正的返回值是后面的decltype(_Tx*_Ty)。为何要将返回值后置呢?如果没有后置,则函数声明时为:
decltype(x*y)multiply(_Tx x, _Ty y)
而此时x,y还没声明呢,编译无法通过。
注意事项
- auto 变量必须在定义时初始化,这类似于const关键字。
定义在一个auto序列的变量必须始终推导成同一类型。例如:
auto a4 = 10, a5 = 20, a6 = 30;//正确
auto b4 = 10, b5 = 20.0, b6 = 'a';//错误,没有推导为同一类型使用auto关键字做类型自动推导时,依次施加一下规则:
如果初始化表达式是引用,则去除引用语义。
int a = 10;
int &b = a; auto c = b;//c的类型为int而非int&(去除引用)
auto &d = b;//此时c的类型才为int& c = 100;//a =10;
d = 100;//a =100;如果初始化表达式为const或volatile(或者两者兼有),则除去const/volatile语义。
const int a1 = 10;
auto b1= a1; //b1的类型为int而非const int(去除const)
const auto c1 = a1;//此时c1的类型为const int
b1 = 100;//合法
c1 = 100;//非法如果auto关键字带上&号,则不去除const语意。
const int a2 = 10;
auto &b2 = a2;//因为auto带上&,故不去除const,b2类型为const int
b2 = 10; //非法这是因为如何去掉了const,则b2为a2的非const引用,通过b2可以改变a2的值,则显然是不合理的。
初始化表达式为数组时,auto关键字推导类型为指针。
int a3[3] = { 1, 2, 3 };
auto b3 = a3;
cout << typeid(b3).name() << endl;程序将输出
int *
若表达式为数组且auto带上&,则推导类型为数组类型。
int a7[3] = { 1, 2, 3 };
auto & b7 = a7;
cout << typeid(b7).name() << endl;程序输出
int [3]
函数或者模板参数不能被声明为auto
void func(auto a) //错误
{
//...
}时刻要注意auto并不是一个真正的类型。
auto仅仅是一个占位符,它并不是一个真正的类型,不能使用一些以类型为操作数的操作符,如sizeof或者typeid。cout << sizeof(auto) << endl;//错误
cout << typeid(auto).name() << endl;//错误
c ++ auto 的使用的更多相关文章
- C++11特性——变量部分(using类型别名、constexpr常量表达式、auto类型推断、nullptr空指针等)
#include <iostream> using namespace std; int main() { using cullptr = const unsigned long long ...
- overflow:hidden与margin:0 auto之间的冲突
相对于父容器水平居中的代码margin:0 auto与overflow:hidden之间存在冲突.当这两个属性同时应用在一个DIV上时,在chrome浏览器中将无法居中.至于为啥我也不明白.
- Android Auto开发之一《开始学习Auto 》
共同学习,共同进步, 转载请注明出处.欢迎微信交流:sfssqs,申请注明"Android Car"字样 ================= =================== ...
- width:100%;与width:auto;的区别
<div> <p>1111</p> </div> div{ width:980px; background-color: #ccc; height:30 ...
- SQl 2005 For XMl 简单查询(Raw,Auto,Path模式)(1)
很多人对Xpath可能比较熟悉,但不知道有没有直接操作过数据库,我们都知道 在Sql2005里公支持的几种查询有Raw,Auto模式,页并没有Path和Elements用法等,如果在2000里使用过 ...
- margin:0 auto;不居中
margin:0 auto:不居中可能有以下两个的原因; 1.没有设置宽度<div style="margin:0 auto;"></div>看看上面的代码 ...
- 初学C++ 之 auto关键字(IDE:VS2013)
/*使用auto关键字,需要先赋初值,auto关键字是会根据初值来判断类型*/ auto i = ; auto j = ; cout << "auto i = 5" & ...
- C++11 - 类型推导auto关键字
在C++11中,auto关键字被作为类型自动类型推导关键字 (1)基本用法 C++98:类型 变量名 = 初值; int i = 10; C++11:auto 变量名 = 初值; auto i ...
- 为什么 "auto a = 1;" 在C语言中可以编译通过?
参照:这里 这让我想起之前看的一部书, int i; 其实是等价与 auto int i; 表示为局部变量 这应该与static是相对的吧?
- wpf *和auto的区别
Auto 表示自动适应显示内容的宽度, 如自动适应文本的宽度,文本有多长,控件就显示多长. * 则表示按比例来分配宽度. <ColumnDefinition Width="3*&quo ...
随机推荐
- ck-reset css(2016/5/13)
/**rest by 2016/05/04 */ * {box-sizing: border-box;} *:before,*:after {box-sizing: border-box;} body ...
- 仿VS安装界面小球滑动效果
在Visual Studio 2010后续版本的安装界面中,可以发现一组小球在滑动表示安装程序正在进行: 于是尝试用CSS实现了一下. 首先需要建立用来表示小球的html结构: <div cla ...
- MongoDB--安装部署
MongoDB安装 说明: 本次安装教程: 版本:mongoDB-3.2.4 安装环境:windows 10 ,64位操作系统 准备:安装包.Robomongo(客户端用于查看mongoDB里面的数据 ...
- 《Java设计模式》之构建者模式
概述: 构造者模式(Builder Pattern):构造者模式将一个复杂对象的构造过程和它的表现层分离开来.使得相同的构建过程能够创建不同的表示,又称为生成器模式. Bu ...
- c++ 通过数据流方式实现文件拷贝
#include "stdafx.h"#include <iostream>#include<fstream>using namespace std;voi ...
- java jdbc oracle ORA-01795: 列表中的最大表达式数为 1000
在操作SQL中存在In的数量如果超过1000条会提示 ORA-01795: 列表中的最大表达式数为 1000 归纳有几种方式出现的: 第一种是:我在上一个 [jdbc 同时执行 查询和删除操]作中 ...
- [URAL-1517][求两个字符串的最长公共子串]
Freedom of Choice URAL - 1517 Background Before Albanian people could bear with the freedom of speec ...
- 【BZOJ4619/3709】[Wf2016]Swap Space/[PA2014]Bohater 贪心
[BZOJ4619][Wf2016]Swap Space Description 你有许多电脑,它们的硬盘用不同的文件系统储存数据.你想要通过格式化来统一文件系统.格式化硬盘可能使它的容量发生变化.为 ...
- 关于dubbo的负载均衡
1 dubbo的集群 将同一个服务部署到多个机器上,然后全部注册到注册中心.这样的多个机器就是一个dubbo集群了. 2 dubbo的负载均衡是怎么回事 由于多台机器上都有同一个服务,因此consum ...
- 解决Ubuntu(乌班图)vi/vim模式下粘贴的代码内容会多出的空格的问题
vi/vim模式下的粘贴 因为linux系统和win系统的差异性,有时候在win环境运行的python代码会放在Linux系统上执行,这个时候就需要把win系统上IDE上的代码copy下来,在Linu ...