C++17 详解 3
本文为 《C++17 in detail》 一书的中文渣中渣译文,不足之处还望指正。
1.1.2 删除关键字 register
关键字 register
在 2011 年(C++11)被弃用,自那以后 register
已经没有意义,现在它被删除。这个关键字仍然被保留,有可能会在未来某个版本重新设计意图(比如关键字 auto
就是复用而来,现在它是一个全新的、更强大的特性)。
如果你用 register
声明变量:
1 | register int a; |
可能会产生如下 warning(GCC8.1):
1 | warning: ISO C++17 does not allow 'register' storage class specifier |
或是 Clang 的一个 error(Clang 7.0):
1 | error: ISO C++17 does not allow 'register' storage class specifier |
扩展:本修改提案:P0001R1
1.1.3 删除弃用的 operator++(bool)
这个操作符已经被弃用很久了。标准委员会早在 1998 年(C++98)就建议不要使用,但直到现在他们才达成一致,把它从标准里删除。
译注:C++ 标准委员会出了名的松散、低效,学院气十足。此处即可见一斑,遑论如网络库、协程库等模块级的更新效率。
如果你尝试编译如下代码:
1 | bool b; |
会生成像下边 GCC(GCC 8.1)类似的 error:
1 | error: use of an operand of type 'bool' in 'operator++' is forbidden in C++17 |
扩展:本修改提案:P0002R1
1.1.4 删除弃用的异常规范
C++17 里,异常规范是类型系统的一部分(在下一章“语言声明”有讨论)。但是标准还是保留了以前被弃用的异常规范,只是没有实际作用。
比如:
1 | void fooThrowsInt(int a) throw(int) { |
请特别留意 throw(int)
。
上边的代码在 C++11 已经被弃用,现在唯一可行的异常声明是 throw()
,意思是这段代码绝不会抛出任何异常。C++11 起建议用 noexcept
代替。
比如 clang 4.0 里会生成如下 error:
1 | error: ISO C++1z does not allow dynamic exception specifications |
扩展:本修改提案:P0003R5
1.1.5 其它被删除的特性
这里列出其它被删除的比较小的内容:
std::random_shuffle
此算法在 C++14 已被标记为弃用。原因是大多数的实现里都用到了 rand()
,这个函数不够高效甚至容易出错(因为它用到了全局状态)。如果你需要同样的功能可以用:
1 | template< class RandomIt, class URBG > |
std::shuffle
接受一个随机数生成器作为第三个参数。更多参见 N4190。
删除旧的 functional
相关
bind1st()
/ bind2st()
/ mem_fun()
等这些函数,在 C++98 时代被引入,现在已经不需要了,你可以用 lambda。更重要的是,这些函数没有更新以处理完美转发、decltype
以及其它 C++11 以来的现代化技术。因此最好不要在现代 C++ 里用它们。更多参见 N4190。
删除三标符(trigraphs)
三标符是一种特殊的字符序列,在一些不支持 7-bit ASCII 码的系统(比如 ISO 646)上有用。比如 ??=
生成 #
,??-
代表 ~
(所有 C++ 源代码字符集都包含在 7-bit ASCII 码中)。在今天三标符已经很少用到,把它从翻译阶段移除,编译处理会更直截了当。参见 N4086。
译注:阅读本书之前,我完全不知道三标符的存在,只能勉强翻译。除上边草案外,还可以参考这里。