--- title: 第 10 章 展望:C++20 简介 type: book-zh-cn order: 10 --- # 第 10 章 展望:C++20 简介 > 内容修订中 [TOC] 本章对即将到来的 C++17 进行介绍,几个月前(2016 年),目前为止,还没有一个正式发布的编译器来编译 C++17 特性的代码,本节作为扩展主题,供对 C++ 的历史进程及其未来发展感兴趣的读者阅读。 ## 10.1 主要入选特性 ### 非类型模板参数的 auto 模板参数分为两种,一种是类型模板参数,也是我们用得最多的一种: ```cpp template auto add(T t, U u) { return t+u; } ``` 里面的 `T` 和 `U` 都是类型模板参数。另一种是非类型模板参数,它可以让不同的字面量成为模板的参数: ```cpp template class buffer_t { public: T& alloc(); void free(T& item); private: T data[BufSize]; } buffer_t buf; // 100 作为模板参数 ``` 遗憾的是我们在编写模板的时候就必须明确非类型模板参数的具体类型,C++17 打破了这一限制,让我们能够在非类型模板参数中使用 `auto` 关键字,从而让编译器推导具体的类型: ```cpp template void foo() { return; } foo<10>(); // value 被推导为 int 类型 ``` ## 10.2 未入选特性 C++ 组委会在讨论投票最终确定 C++17 有很多提案,诸如 **Concepts**/**Ranges**/**Module** 等等,其中最受关注的就是 **Concepts**,可惜这一提案最终被拒,作为技术规范(Technical Specifications, TS) 将其发布。 ### Concepts TS **Concepts** 是对 C++ 模板编程的进一步增强扩展。简单来说,**Concepts** 是一种编译期的特性,它能够让编译器在编译期时对模板参数进行判断,从而大幅度增强我们在 C++ 中模板编程的体验。使用模板进行编程时候我们经常会遇到各种令人发指的错误,这是因为到目前为止我们始终不能够对模板参数进行检查与限制,例如下面简单的两行代码会造成大量的几乎不可读的编译错误: ```cpp #include #include int main() { std::list l = {1, 2, 3}; std::sort(l.begin(), l.end()); return 0; } ``` 而这段代码出现错误的根本原因在于,`std::sort` 对排序容器必须提供随机迭代器,否则就不能使用,而我们知道 `std::list` 是不支持随机访问的。用 **Concepts** 的话来说就是:`std::list`中的迭代器不满足`std::sort`中随机迭代器这个 **Concepts**(概念) 的 **requirements**(要求)。有了 **Concepts**,我们就可以这样: ```cpp template requires Sortable // Sortable 是一个 concept void sort(T& c); ``` 缩写为: ```cpp template // T 是一个 Sortable 的类型名 void sort(T& c) ``` 甚至于直接将其作为类型来使用: ```cpp void sort(Sortable& c); // c 是一个 Sortable 类型的对象 ``` 遗憾的是,C++组委会没有将 **Concetps** 纳入新标准,而是将其作为TS正式发布(其实早在 C++11 最终定案之前就已经有 **Concepts** 的呼声了,但 Concepts TS 是2015年才完整正式发布),也就是我们现在看到的 Concepts TS。C++组委会拒绝将 Concepts 纳入新标准的原因其实很简单,并不是技术层面上的原因,纯粹是觉得它还不够成熟。 Concepts TS 的发布到最后一次 C++17 的讨论会只相隔了不到四个月的时间,**Concepts** 的(唯一)实现只存在于一个未发布的 gcc 版本中。而 gcc 中关于 **Concepts** 的实现就是由撰写 Concepts TS 的人开发的,虽然它能够进行相关测试,但还没有认真讨论过这份 TS 会产生哪些不良后果,更何况这份 TS 都没有被测试过。此外,已知的 **Concepts** 的一个明显的作用就是去辅助实现 Ranges TS 等提案,但实际上它们也没有被选入 C++17,所以可以把 **Concepts** 继续延后。 ## 总结 总的来说,类似于 Concepts/Ranges/Modules 这些令人兴奋的特性并没有入选至 C++17,这注定了 C++17 某种意义上来说相较于 C++11/14 依然只是小幅度更新,但我们有望在 C++2x 中看到这些东西的出现,这些内容对于一门已经三十多岁『高龄』的编程语言,依然是充满魅力的。 [返回目录](./toc.md) | [上一章](./09-others.md) | [下一章 附录:进一步阅读的学习材料](./appendix1.md) ## 进一步阅读的参考资料 1. [Final features of C++17](https://meetingcpp.com/index.php/br/items/final-features-of-c17.html) 2. [C++17: will it be great or just ok?](https://codeplay.com/public/uploaded/filehost/0cbdaf_c++17post-oulu2016.pdf) 3. [Why Concepts didn't make C++17?](http://honermann.net/blog/2016/03/06/why-concepts-didnt-make-cxx17/) 4. [C++11/14/17/20 编译器支持情况](http://en.cppreference.com/w/cpp/compiler_support) ## 许可 知识共享许可协议 本教程由[欧长坤](https://github.com/changkun)撰写,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](../../LICENSE)。