C++11精要学习:为什么auto总是第一个被提到

为什么auto排第一

C++程序员去面试,作为暖场问题,总会让先列举一下知道哪些C++11的新特性。这样一是为了考察C++程序员对语言本身的熟悉程度,二来可以在对方的回答中找到进一步的突破口。

程序员面试总会有一种感觉,就是“我会的都没问,问的都是我不会的”。这其实并不奇怪,因为面试官与应聘者都是技术人,一个技术点了解怎样,交流一下是能听得出来的。所以面试官确信应聘者已经掌握的知识,就不会再浪费时间去多问了,要问的正是更加深入细节的部分。

作为C++11的新特性,auto之所以能排在答案的首位,很大可能是因为其首字母a恰好也在排在字母表的首位。当然,我这只是先开个玩笑,现实是不会这么肤浅的。

auto关键字首先应该是功能明确易理解,而且使用不复杂。先说这个答案,哪怕是被问到,相信也能对付得下来。这时候应聘者脑海里应该出现如下的一行简洁代码了:

auto a = 0;

行了,有什么问题就放马过来吧。不就是个类型自动推导么,变量a的类型取决于等号右边所赋的值。所以上面示例中的a就是int型。甚至还能多唠几句,告诉面试官这是编译期特性,不同于其他动态类型的语言例如python是在运行期确定变量类型的。

很好,有的面试官听到这里也许会很满意,但也有的会微笑着打断应聘者,拿起笔在A4空白稿纸上写下两行代码:

auto a = 0;
auto b = &a;

问:b是什么类型?

auto也能挖坑

可能这时候大多数程序员还是能答对的,b的类型是int * ,一个指向整型的指针类型。好吧,追杀这才刚刚开始,接下来还有:

auto a = 0;
auto b = &a;
auto &c = a;
auto d = c;

问:d是什么类型?

能不带一点儿犹豫地喊出d是int型的,我敬你是条汉子。因为面试官不会让这个节奏如此从容,而是会故意面无表情,加快语速提出问题。如果应聘者顺着惯性思维判断c是一个整型引用,那么d也整型引用,那就掉到坑里去了。其实答案还是整型。

不要着急擦脑门上的汗,连环追杀下一波已至。面试官又接着写下:

auto a = 0;
auto b = &a;
auto &c = a;
auto d = c;
const auto e = a;
auto f = e;

问:f是什么类型?

也许你很想说f是const int,但如果真是这样那就不叫坑了。答案还是int。这会儿也许有的应聘者想掀桌子了,但不要急,如果侥幸躲过这一波,管你出什么题,我就死咬着int不松嘴。那么下面的问题就是专门为你挖的坑:

auto a = 0;
auto b = &a;
auto &c = a;
auto d = c;
const auto e = a;
auto f = e;
const auto &g = a;
auto &h = g;

问:h是什么类型?

好吧,不卖关子了,答案是const int &。如果这些问题都能自信答对,请收我为徒吧。其实要再找点乐子也不是不可以,就问:C++98里能使用auto关键字吗?

你也许很想说不能,但知道这么回答很大概率又掉到另一个坑里去了。答案是以前就有的,只不过它用于定义局部变量。就是如果你要在方法体内定义一个局部变量,应该写成auto int a = 0;。但显然你没看过这样的代码,写成int a = 0;才应该是天经地义的。

所以C++标准委员会都觉得过意不去,才会在C++11中给auto赋予全新的含义,就是表示为类型指示符,用以在编译期做隐式类型推导。其实auto还能挖出许多坑来,例如auto能用于函数参数吗?能用于非静态成员变量吗?能用于数组吗?

所以抓住下面五条规则 ,我想一定能帮助应聘者从容地避免踩坑。

  1. 当不声明为指针或引用时,auto的推导结果和初始化表达式抛弃引用和const限定符后类型一致;
  2. 当声明为指针或引用时,auto的推导结果将保持初始化表达式的const属性;
  3. auto不能用于函数参数;void func(auto a = 1) {},编译失败;
  4. auto不能用于非静态成员变量;struct foo {auto a = 0;};,编译失败;
  5. auto不能用于定义数组;int arr[10] = {0}; auto ar[10] = arr;,编译失败。

使用场景

学习C++这样博大精深的编程语言,不多花点体力和脑力是不行的。也许你会觉的,就一个auto挖出来的那些坑,真的都会在工作中用得上吗?很有可能的情况是,80%的场景下只使用到了auto那20%最常用的特性。

答案可能真的是如此,但这并不能成为我们学习一门编程语言就浅尝辄止的理由。知其然也要知其所以然,方能在工作中将C++的威力发挥出来。其实C++无论是入门还是精通都不容易,很多初学者在尝试学习之后都会转向java或python这样的语言。

选择是自己作的,谁也无可厚非。但如果真的想要坚持成为一名合格的C++程序员,那还是继续学习吧。

auto最直观的作用,就是简化了变量类型的声明,只需要通过直接定义变量的值,就可以确定它的类型。这看起来与动态类型的语言颇为相似,但有着根本上的不同。因为auto在C++中是在编译期被执行的,代码文本被编译为二进制可执行程序之后,变量的类型都必须是确定的。

所以我们在使用auto之前应该很清楚地知道,自己要声明的变量是什么类型。不能是模棱两可的状态下,就想依靠auto的特性把代码编译完了事。在运行中就极有可能出现那种最难调的bug,“我看不出代码哪里不对,但运行就是不符合预期”。说到底,还是功夫不够深,学习这事真是马虎不得。

一种典型的场景,就是在使用STL容器时,声明一个迭代子进行遍历时,会写出很长的代码来,如下所示:

std::map<int, string> someMap;
// insert data to someMap
for (std::map<int, string>::iterator it = someMap.begin(); it != someMap.end(); it++) {
    // access it data
}

那么,对其使用auto进行改良的一种写法,就可以是:

std::map<int, string> someMap;
// insert data to someMap
for (auto it = someMap.begin(); it != someMap.end(); it++) {
    // access it data
}

当然,在实际工程中都不会仅是如示例中这么简单,会有和业务相关的、更加复杂的类和对象。而从代码书写上来说,STL容器的使用细节与业务本身并无太大关联,将大段烦琐的变量声明使用auto代替,代码的可读性自然得到肉眼可见的提升。上述示例只是使用场景之一,就像给auto挖坑一样,使用auto改善代码可读性也会有许多可能的场景。

结语

auto在C++11中的新作用,也是顺应编程语言发展的趋势。而这种变化也的确给C++这样一门“古老”的语言带来了新的生机,C++11中还有诸多新特性能让我们感受到与过去的不同。

在auto的使用上,切忌认为新的就是好的,一下就把编程习惯都给改变了。滥用以至错用,都不是一名成熟的程序员所为。而C++本身也是一门兼具工程和研究性质的编程语言,它提供了许多可能,但并不意味着就可以随意使用。它还需要程序员以探索的精神不断尝试、总结,最终形成自己的独门心法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值