1.  auto关键字

(1)auto的作用是让编译器自动推断变量的类型,而不需要显式指定类型。这种隐式类型的推导发生在编译期

(2)auto并不能代表实际的类型声明,只是一个类型声明的“占位符”

(3)auto声明的变量必须马上初始化,以让编译器推断出它的实际类型。

【编程实验】auto的基本用法

//1.1.cpp

#include <iostream>
#include <typeinfo> //编译:vc: cl 1.1.cpp
// g++: g++ -std=c++11 1.1.cpp using namespace std; double foo(){return 0.0;}; struct m{
int i;
}sm; int main()
{
auto x = ; //x:int(其实1为const int类型,auto丢弃const)
auto y = foo(); //y:double
auto z = sm; //m1: struct m const auto* u = &x, v = ; //u: const int*, v: int类型(注意不是const int)
//auto的类型由u的类型决定,因此v不能初始化为6.0之类
static auto w = 0.0; //w:double; //auto s; //error: 无法推导。s必须被初始化 cout << "x: " << typeid(x).name() << endl;
cout << "y: " << typeid(y).name() << endl;
cout << "z: " << typeid(z).name() << endl;
cout << "u: " << typeid(u).name() << endl;
cout << "v: " << typeid(v).name() << endl;
cout << "w: " << typeid(w).name() << endl; return ;
}
/*输出结果:
x: int
y: double
z: struct m
u: int const *
v: int
w: double
*/

2. auto的推导规则

(1)当直接使用auto声明变量时(如auto varName),auto的推导结果和初始化表达式抛弃引用cv限定符(const和volatile)后的类型一致。即auto将丢弃初始化表达式的cv属性。(原因 :auto varName说明varName是按值传递,它是原对象/变量的副本,所以可以在副本上进行修改操作,所以并不需要保留const等属性)

(2)当auto后面显式添加&时(如auto& varName)时,推导结果才会保留初始化表达式的cv属性和引用。(原因:由于引用代表对象本身,所以原对象/变量如果有cv属性,则应该被保留下来)

(3)当auto*或auto推导结果为指针,保留指针的底层cv操作符。除2、3两种情况外,均不保留cv和引用。

(4)同一赋值语句中,用auto来声明多个变量类型时,只有第一个变量用于auto的类型推导,然后推导出来的数据类型作用于其他变量。因此,这些变量的类型必须相同。否则,编译器则会报错。

(5)auto是从左向右推导,类似于字面替换的方式进行。

(6)new和初始化列表中也可以使用auto关键字

【实例分析】auto和auto&(auto*)的差异

//1.2.cpp

#include <iostream>
#include <typeinfo>
using namespace std; //编译:vc: cl 1.2.cpp
// g++: g++ -std=c++11 1.2.cpp double foo(){return 0.0;}; int main()
{
auto x = ; //x: int(注意1为const int类型,但auto会丢弃const限定符)
int* y=&x; auto* a = &x; //a: int* auto: int
auto b = &x; //b: int* auto: int*
auto& c = x; //c: int&, auto: int //auto和auto&:当初始化表达式为引用时
auto d = c; //d: int, auto: int(注意:c为引用,但会被auto会丢弃,故d为int)
auto& e = c; //e: int&, auto: int(auto&会保留引用和cv限制符) //auto和auto&: 当初始化表达式带cv限定符时
const auto f = x; //f: const int, auto: int
auto g = f; //注意此处:g: int(因为auto会丢弃初始化表达式的cv限定符) auto& h = f; //注意此处:h:const int&(auto&会保留f的const属性)
auto* i = &f; //注意此处:i:const int*(auto*会保留f的const属性) //auto从左向右推导
auto o = , &p = o, *q = &p; //o: int, p: int&, q: int*
auto r = , s = ; //auto根据r推导出auto为int,因此s为int //单行声明变量的陷阱(建议:多变量尽量分多行声明)
const auto* m = &x, n = ; //m: const int*,但n为int(注意不带const) //初始化列表中使用auto
auto x1(); //x1: int
auto x2 {}; //x2: int //new中使用auto
auto x3 = new auto(); cout << "a: " << typeid(a).name() << endl;
cout << "b: " << typeid(b).name() << endl;
cout << "c: " << typeid(c).name() << endl;
cout << "d: " << typeid(d).name() << endl;
cout << "e: " << typeid(e).name() << endl;
cout << "f: " << typeid(f).name() << endl;
cout << "g: " << typeid(g).name() << endl;
cout << "h: " << typeid(h).name() << endl;
cout << "i: " << typeid(i).name() << endl;
cout << "o: " << typeid(o).name() << endl;
cout << "p: " << typeid(p).name() << endl;
cout << "q: " << typeid(q).name() << endl;
cout << "r: " << typeid(r).name() << endl;
cout << "m: " << typeid(m).name() << endl;
cout << "n: " << typeid(n).name() << endl;
cout << "x1: " << typeid(x1).name() << endl;
cout << "x2: " << typeid(x2).name() << endl;
cout << "x3: " << typeid(x3).name() << endl; return ;
}
/*输出结果
a: int *
b: int *
c: int
d: int
e: int
f: int
g: int
h: int
i: int const *
o: int
p: int
q: int *
r: int
m: int const *
n: int
x1: int
x2: int
x3: int *
*/

3. auto的限制

(1)auto不能用于函数参数。如果需要泛型参数,可借助于模板

(2)auto不能用于非静态成员变量

(3)auto无法定义数组

(4)auto无法推导模板参数

【实例分析】auto使用受限

//1.3.cpp

#include <iostream>
#include <vector>
#include <typeinfo>
using namespace std; //编译:vc: cl 1.3.cpp
// g++: g++ -std=c++11 1.3.cpp void func(auto a = ){} //error: 不能用于函数参数。泛型参数可借助模板来实现 struct Foo
{
static const auto var2 = ; //OK: 静态成员函数,可用auto推导 auto var1 = ; //error:非静态成员函数,不能用auto推导
}; int main()
{
char x[] ={};
auto y = x; //OK: y: int*(注意:不是char[3])
auto z[] = x; //error: auto无法定义数组 vector<auto> v = {}; //error: auto不能用于模板参数 return ;
}

4. auto的优势

(1)auto最大优势简化代码,特别是当声明的变量类型比较复杂的时候。

(2)避免类型声明时的错误。C/C++存在很多隐式或用户自定义的类型转换规则,这些规则不容易记忆,这时auto就可以用于自动推导。

(3)auto的“自适应”能够在一定程序上支持泛型编程。如strlen函数返回值,在32位编译环境下,返回一个4字节的整型,64位返回一个8字节的整型。可以使用auto关键字达到代码跨平台的效果。

【实例分析】auto的优势

//1.4.cpp

#include <iostream>
#include <map> //编译:vc: cl 1.4.cpp
// g++: g++ -std=c++11 1.4.cpp //1. 简化迭代器变量的声明
void func()
{
std::map<double, double> resMap;
//优化前
// std::map<double, double>::iterator = it = resMap.begin();
// for(; it != resMap.end(); ++it){
// //do something;
// } //优化后
for(auto it = resMap.begin(); it != resMap.end(); ++it){
//do something
}
} //2. 避免类型声明错误
class PI
{
const float val = 3.1415927f;
public:
double operator* (float v){
return (double)val * v; //精度被扩展
}
}; //3. auto对类型的自适应
template <typename T1, typename T2>
double Sum(T1& t1, T2& t2)
{
auto s = t1 + t2; //s的类型会在模板实例化时被推导出来
} int main()
{
//demo: 避免auto类型声明
float radius = 1.7e10;
PI pi; //operator*的返回值为double,但使用PI这个类的人可能不知道
//PI类的设计者为了避免数据上溢而返回了double类型。这时可以
//用auto来自动推导operator*的返回类型。同时假如PI的作者改动
//了PI的定义,将operator*的返回值改为了long double,此时main
//函数并不需要修改,因为auto会“自适应”新的类型
auto circumference = * (pi * radius); //demo: auto的自适应
int a = ;
long b = ;
float c = 1.0f, d = 2.3f;
auto e = Sum<int, long>(a, b); //s==> long;
auto f = Sum<float, float>(c, d); //s==>float; return ;
}

第1课 类型推导(1)_auto关键字的更多相关文章

  1. 第2课 类型推导(2)_decltype关键字

    1. decltype关键字 (1)auto所修饰的变量必须被初始化,编译器才能通过初始化来确定auto所代表的类型,即必须先定义变量. (2)decltype可以在编译期推导出一个变量或表达式的结果 ...

  2. 第4课 decltype类型推导

    第4课 decltype类型推导 一.decltype类型推导 (一)语法: 1.语法:decltype(expr),其中的expr为变量(实体)或表达式 2.说明: ①decltype用于获取变量的 ...

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

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

  4. 第3课 auto类型推导(2)

    第3课 auto类型推导(2) 一.使用auto的优势 (一)避免使用未初始化变量 (二)可简化变量/对象类型的声明 (三) 在某些场合无法判断出类型时,可用auto自动推导(如lambda表达式) ...

  5. 第2课 auto类型推导(1)

    第2课 auto类型推导(1) 一.auto类型推导 (一)与模板类型推导映射关系 1.auto类型推导与模板类型推导可以建立一一映射关系,它们之间存在双向的算法变换.auto扮演模板中T的角色,而变 ...

  6. c++相关的类型推导

    c++11和boost库增加许多关于类型推导(编译期)的关键字和类型, 用好这些机制, 对于编写项目的一些组件帮助颇大.正所谓工欲善其事,必先利其器. 1.初始化某种类型的变量 auto var = ...

  7. Swift学习(三)类型推导&基本运算&分支&循环

    一.Swift中类型推导&基本运算 Swift中类型推导 如果一个标识符在定义时有直接赋值,那么可以根据后面赋值的类型,来推导出前面标识符的类型,这样前面标识符的(:类型)可以省略 查看标识符 ...

  8. C++11类型推导

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

  9. 《Effective Modern C++》翻译--条款2: 理解auto自己主动类型推导

    条款2: 理解auto自己主动类型推导 假设你已经读过条款1关于模板类型推导的内容,那么你差点儿已经知道了关于auto类型推导的所有. 至于为什么auto类型推导就是模板类型推导仅仅有一个地方感到好奇 ...

随机推荐

  1. 程序设计实践 (Brian W. Kernighan Rob Pike 著)

    第1章 风格 1.1 名字 1.2 表达式和语句 1.3 一致性和习惯用法 1.4 函数宏 1.5 神秘的数 1.6 注释 1.7 为何如此费心 第2章 算法与数据结构 2.1 检索 2.2 排序 2 ...

  2. IDEA基本設置

    2.界面字体大小设置 File菜单->Settings->Appearance->Override default fonts by(not recommended):Name:宋体 ...

  3. 大数据框架对比:Hadoop、Storm、Samza、Spark和Flink--容错机制(ACK,RDD,基于log和状态快照),消息处理at least once,exactly once两个是关键

    分布式流处理是对无边界数据集进行连续不断的处理.聚合和分析.它跟MapReduce一样是一种通用计算,但我们期望延迟在毫秒或者秒级别.这类系统一般采用有向无环图(DAG). DAG是任务链的图形化表示 ...

  4. linux项目部署常用命令

    原文出处:http://blog.csdn.net/u013628152/article/details/45847013 1:执行命令#find / -name tomcat,系统将列出所有tomc ...

  5. redmine一键安装(项目管理、Bug管理、任务跟踪、代码管理、日报等等)

    1,下载一键安装包(64位系统) https://bitnami.com/stack/redmine 2,帮助文档(安装引导) http://www.360doc.com/content/15/033 ...

  6. 【转】使用kettle工具遇到的问题汇总及解决方案

    使用kettle工具遇到的问题汇总及解决方案   转载文章版权声明:本文转载,原作者薄海 ,原文网址链接 http://blog.csdn.net/bohai0409/article/details/ ...

  7. windows的消息传递--消息盒子

    例如对windows发消息让文本选中.     SendMessage(Text1.hwnd,EM_GETSEL,0,-1 ); EC_LEFTMARGIN(&H1) EC_USEFONTIN ...

  8. 跟着未名学Office - 高效工作Outlook

    目录 第一篇邮件与联系人    1 第一节    使用与技巧    1 第二节    高效    11 第二篇    事务助手    21 第一节    日程管理    21 第二节    任务    ...

  9. 【springboot】之Application配置

    # =================================================================== # COMMON SPRING BOOT PROPERTIE ...

  10. 关于 TensorFlow

    TensorFlow 是一个用于人工智能的开源神器 TensorFlow中文社区    http://www.tensorfly.cn/   文档 TensorFlow™ 是一个采用数据流图(data ...