
文章插图
来源:Pexels
作为一种计算机语言,C++经历了许多发展变化 。
当然,这些改变并不是一蹴而就的 。C++曾经缺乏活力与创新,因此很不受欢迎 。
但是在C++标准委员会决定加速发展这个语言之后,形势发生了改变 。
2011年起,C++一跃成为了具有活力、不断演进、广受喜爱的计算机语言 。
C++蜕变后也并没有简单多少,仍是最难的编程语言之一 。但是,C++确实比之前更加人性化了 。
本文要讲的是的C++的一些新特性(以有8年历史的C++11为例),相信每个程序员都会对这个话题感兴趣 。
注:本文略过了一些高级特性 。
1. 关键字auto
当C++11第一次引入auto时,程序员们纷纷喜极而泣!
auto的意义是使C++编译器可以在编译时推导数据类型,这样就不用每次都要声明数据类型了 。当数据类型为map<string,vector<pair<int,int>>>时尤为便捷 。

文章插图
没有initializer,就无法声明数据类型(见第五行) 。这是说得通的 。第五行指令并没有让编译器推导数据类型 。
起初,auto的功能比较有限 。在之后新版本的C++中,auto的功能越来越强大 。

文章插图
第七行和第八行中使用了括号初始化 (bracketedinitialization),这也是C++11的新特性之一 。
请注意使用auto时,编译器必须能够推导数据类型 。
一个有趣的问题是:如果写下autoa = {1, 2, 3}会发生什么?这是个编译错误吗?是一个矢量吗?
实际上,C++11引入了std::initializer_list<type>.如果声明auto,花括号初始化列表会被当做轻量级容器 。
最终,正如前文所言,当数据结构复杂时,编译器类型推导很有帮助:

文章插图
别忘了检查第25行!auto [v1,v2] = itr.second纯粹是C++17的新特性 。这个特性叫做结构化绑定 。在旧版本C++中,程序员需要单独获取每个变量 。但是结构化绑定给这一过程带来了便利 。此外,如果想获得数据使用引用(reference),只需要加上一个symbol--auto&[v1,v2] = itr.second.
2. Lambda表达式
C++11引入了lambda表达式,这类似于JAVAScript里的匿名函数 。它们都是函数对象,没有名字,且基于简洁的语法在不同作用域上捕获变量 。它们也可以被分配给变量 。
如果需要在代码中进行一些小而快的操作,又不愿意为此单独写一个函数,那么Lambdas很有用 。另一种常见用法是将lambdas作为比较函数 。

文章插图
以上例子可以说明很多问题 。
首先,请注意花括号初始化是如何提升权重的 。然后是通用的begin(),end() (这也是C++11的新增部分) 。接着是作为数据比较器的lambda函数 。lambda函数的参数被声明为auto(这是C++14的新增部分) 。在C++14之前是不能对于函数参数使用auto 的 。
正如现代C++的awesome库中定义的那样:
· []—不捕获任何对象 。所以不能在lambda表达式内使用全局作用域的局部变量,只能使用参数 。
· [=]— 按值捕获作用域中的局部对象(局部变量,参数) 。只可使用不可修改 。
· [&]—按引用捕获作用域中的局部对象(局部变量,参数) 。可以被修改 。例子如下 。
· [this]—按值捕获this 指针 。
· [a, &b]—按值捕获对象a ,按引用捕获对象b 。
所以,如果想在lambda函数内部将数据转换为其他格式,可以利用作用域的优势来运用lambda.比如:

文章插图
在上面这个例子中,如果在lambda表达式中按值捕获([factor])局部变量,则不能改变第五行的factor.原因很简单——没有权限 。
最终,请注意示例中使用了val 作为引用 (reference). 这确保了lambda函数内部的任何变化都会改变vector.
3. if/switch内的初始化语句
C++17的这个特性十分讨喜:
推荐阅读
- 中秋节这天为什么要吃月饼呢 中秋节后超市月饼怎么处理
- 针灸减肥有奇效开始之前需要了解这6点
- 男女针灸戳身体这处缓解压力还补肾
- 梅花针治疗疾病帮助大这些人不能用梅花针
- 注意!梅花针这样敲可以美容
- 如何做汤圆
- 原来用热水敷眼睛有这么多作用
- 历史上真有苏麻喇姑这个人吗 苏麻喇姑为什么地位那么高
- 凉茶是药不是茶 这几类人不宜多喝
- 你知道这些独特的饮茶习俗吗
