8. C++17:大海迷航
在经过 C++14 这个小版本标准之后,C++17 [Smith 2017] 原本被看作是一个大版本。C++17 有很多新的特性,但没有一个我认为称得上重大。尽管我们已经有给 C++11 和 C++14 带来成功的工作流程,标准社区也更丰富、更强大、更热情,但对于 C++17 的关键问题是:为什么所有的辛劳却没有带来更显著的改进?
C++17 有大约 21 个新的语言特性(取决于你的计数方式),包括:
- 构造函数模板参数推导——简化对象定义(§8.1)
- 推导指引——解决构造函数模板参数推导歧义的明确写法(§8.1)
- 结构化绑定——简化写法并消除一种未初始化变量的来源(§8.2)
inline
变量——简化了那些仅有头文件的库实现中的静态分配变量的使用 [Finkel and Smith 2016]- 折叠表达式——简化变参模板的一些用法 [Sutton and Smith 2014]
- 条件中的显式测试——有点像 for 语句中的条件(§8.7)
- 保证的复制消除——去除了很多不必要的拷贝操作 [Smith 2015]
- 更严格的表达式求值顺序——防止了一些细微的求值顺序错误 [Dos Reis et al. 2016b]
auto
当作模板参数类型——值模板参数的类型推导 [Touton and Spertus 2016]- 捕捉常见错误的标准属性——
[[maybe_unused]]
、[[nodiscard]]
和[[fallthrough]]
[Tomazos 2015] - 十六进制浮点字面量 [Köppe 2016a]
- 常量表达式
if
——简化编译期求值的代码 [Voutilainen and Vandevoorde 2016]
不幸的是,这并不是完整的功能扩展列表。相当一部分是如此之小,我们很难简单地描述它们。
C++17 标准库中增加了大约 13 个新特性,并加上了许多小的修改:
optional
、any
和variant
——用于表达可选
的标准库类型(§8.3)shared_mutex
和shared_lock
(读写锁)和scoped_lock
(§8.4)- 并行 STL——标准库算法的多线程及矢量化版本(§8.5)
- 文件系统——可移植地操作文件系统路径和目录的能力(§8.6)
string_view
——对不可变字符序列的非所有权引用 [Yasskin 2014]- 数学特殊函数——包括拉盖尔和勒让德多项式、贝塔函数、黎曼泽塔函数 [Reverdy 2012]
尽管我也喜欢 C++17 中的某些功能,但令人困扰的是这些功能没有统一的主题,没有整体的规划,似乎只是由于可以达到投票多数而被扔进语言和标准库中的一组聪明的想法
。这种状况可能给未来语言的发展带来更大的弊端,因此必须采取一些措施做出改变 [Stroustrup 2018d]。方向小组的成立是 WG21 针对这个问题的回应(§3.2)(§9.1)的一部分。
不可否认,C++17 提供了一些可以在小方面帮助大多数程序员的东西,但没有什么可以让我认为是重大的。在这里,我将重大
定义为对我们思考编程和组织代码的方式产生影响
。在此,我描述了我猜想会产生最大积极影响的功能。
我也检查了一些尽管经过严肃考虑、仍没有进入 C++17 标准的例子:
- §6.3.8:概念(C++20)
- §8.8.1:网络库
- §8.8.2:点运算符(
operator.()
) - §8.8.3:统一函数调用
- §8.8.4:简单类型的默认比较运算符
==
、!=
、<
、<=
、>
和>=
- §9.3.2:协程(C++20)
我怀疑如果它们被采纳的话,其中的任何一项都会成为 C++17 最重要的特性之一。它们符合 C++ 应该成为什么的一致观点(§9.2);即使只有少数几项,也会极大地改变 C++17 的使用方式。
在 C++11 中我看到了相互支持的特性网,它们带来了更好的代码编写方式。对于 C++17,我没有看到。但是,C++20 完善了这样一张网,使 C++ 又向前迈进了一大步(§9)。可以说 C++17 只是通向 C++20 路上的垫脚石,但是委员会的讨论对此毫无暗示,重点始终放在单独的特性上。我甚至听到有人说列车模型
(§3.2)不适合长期规划;事实并非如此。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论