2017年12月6日,C++17 标准正式发布!鉴于目前国内介绍 C++17 新特性的资料不多,而且就算提到了 C++17,也无非以下两类:一类只是提了一下有哪些新特性,而没详细讲解用法;另外一类就是在畅想 concept , module 等本来期望着能进 C++17, 最终却无缘入围的功能。因此,本人决定从国外的视频中搬运一些详解 C++17 新特性的学习资料,供大家围观。

本文部分内容参考了 Bryce Lelbach 主讲的视频 C++17 Features – An Introduction to C++17 Via Inspiring Examples ,这位老兄特别健谈,一个人连续讲解了一个半小时没有休息,向他致敬!另外,由于本人最近手头事有点多,所以边写边更,速度慢请见谅!理解有误的地方也请各位同仁批评指正!

构造函数的模板推导 (Class template deduction)

直接上代码,大家先有个直观感受

#include <iostream>
#include <string>using namespace std;int main()
{pair p(3, 3.5); //nowcout << p.first << "  " << p.second << endl;pair <int, double> p2(3, 3.5); //beforecout << p2.first << "  " << p2.second << endl;pair p3(3.5,"abc"); //now, 自动推导为 pair<double, const char*> 类型cout << p3.first << "  " << p3.second << endl;/*p3.second.length(); //提示出错, gcc 7.1 的提示信息为:[Error] request for member 'length' in 'p3.std::pair<double, const char*>::second', which is of non-class type 'const char*'*/return 0;
}

可以看到,在以前,必须手动指定 pair 的模板参数。现在呢,可以通过你传进去的构造参数的类型自动推导生成的 pair 的类型了。不过要当心了,看那个 p3 ,第二个模板参数推导出的类型是 const char* ,不是 string !

当然,这种自动模板类型推导也适用于 vector , tuple (元组) 等其他容器,例如:

#include <iostream>
#include <vector>using namespace std;int main()
{vector v = {1.2, 5.6, 8.7};for(const auto & ele : v) {cout << ele << endl;}return 0;
}

结构化绑定 (Structured bindings)

记得以前学 C 语言时,要想让一个函数能返回两个值的话,用的是参数列表里传指针的形式;或者你自己再定义一个结构体也行。后来么,有了 C++ 里的 pair ,虽然理论上可以用这个返回两个参数,但是实际操作中用的还是不多。

当然了么,人心是贪婪的。既然能返回两个值,我肯定就会想着如何返回三个值 ~~~ 貌似用 tuple 里的 get<0>() get<1>() get<2>() 太烦了点。

而结构化绑定就是这样一种利器,能帮你更优雅的实现这些想法。

#include <iostream>
#include <string>
#include <tuple>using namespace std;pair<int, string> get_record()
{return pair(0, "Jebediah");
}auto get_record2() //这个函数的返回值类型声明利用了 C++14 中自动推导返回类型的特性, 等价于下面一个版本
{return tuple(1, "Bill", "engineer");
}/*
tuple<int, const char*, const char*> get_record2()
{return tuple(1, "Bill", "engineer");
}
*/int main()
{auto [id, name] = get_record();cout << id << "   " << name << endl;auto [id2, name2, job2] = get_record2();//注意,这里要是不写成 id2, name2, ... 的话,就和上面的变量名起冲突了cout << id2 << "   " << name2 << "   " << job2 << endl;return 0;
}

最近 map 这个容器用的挺多的,干脆来介绍一下它在 map 中的一些应用:

#include <iostream>
#include <string>
#include <map>using namespace std;int main()
{map<int, string> m = {{0, "Jebediah"},{1, "Bob"},{2, "Bill"},}; //这边貌似就不能用 map m = { {0, "Jebediah"}, ...}; 这种方式做自动类型推导了, 应该是标准还没发展到那么智能吧//g++ 7.1 报错:   [Error] no matching function for call to 'map(<brace-enclosed initializer list>)'/* now in C++17 */for(const auto & [key, value] : m) {cout << key << "   " << value << endl;}cout << endl;/* before */for(const pair<const int, string> & result : m) {cout << result.first << "   " << result.second << endl;}cout << endl;/*当然,如果你觉得用 first, second 去取 key, value 很丑陋的话,你也可以借助 .* 运算符给他们取个别名,借机骚一波*/typedef pair<const int, string> find;const int find:: * key = &find::first;string find:: * value = &find::second;for(const pair<const int, string> & result : m) {cout << result.*key << "   " << result.*value << endl;}/* 不过鉴于用 .* 运算符写起来太晦涩了,所以第三种写法就算了吧 */return 0;
}

你可能要说了,C++11 里的 tie 也能完成这些功能啊。不好意思,Bryce 同志在他的幻灯片里罗列了一大堆 tie 的劣处:

/* 1 */
std::tuple<double, double, double> t = // ...double x, y, z;std::tie(x, y, z) = t; // correct /* 2 */
std::tuple<double, double, double> t = // ...double x, y, z;std::tie(y, y, z) = t; // ^ UH-OH : no warning for repeated names./* 3 */
std::tuple<double, double, double> t = // ...double &x, &y, &z; // COMPILE ERROR// Uninitialized refs.std::tie(x, y, z) = t;/* 4 */
std::tuple<double, double, double> t = // ...double const x, y, z;std::tie(x, y, z) = t; // COMPILE ERROR// Assignment to const.

选择语句中的初始化器 (Selection Statements with Initializers)

顾名思义,就是现在能在 if 语句中做一些初始化工作了

#include <iostream>
#include <string>
#include <map>using namespace std;int main()
{map<int, string> m = {{0, "Jebediah"},{1, "Bob"},{2, "Bill"},};/* now */if(auto it = m.find(1); it != m.end()) {auto [key, value] = *it;cout << value << endl;}/* before */auto it = m.find(1);if(it != m.end()) {cout << it->second << endl;}return 0;
}

更多特性,未完待续。。。

C++17 部分实用特性相关推荐

  1. Redis高级实用特性:发布及订阅消息

    在之前的文章中,介绍过Redis数据库高级实用特性中的持久化机制,今天为大家介绍Redis的另一高级实用特性--发布及订阅消息. 发布订阅(pub/sub)是一种消息通信模式,主要的目的是解耦消息发布 ...

  2. Redis学习第八课:Redis高级实用特性(一)

    Redis高级实用特性 注:我学习的环境是vmware7.1 + ubantu10.10+ redis 3.0.2 1.安全性 设置客户端连接后进行任何其他指定前需要的密码.因为redis速度相当快, ...

  3. 一本深入探讨C++11~C++17最新语言特性的书推荐给你

    近10年来C++的更新可谓是非常频繁,这让我在2017年时感受到了一丝不安.那个时候我发现在开源平台上已经有很多项目采用C++11和C++14标准编写,其中不乏一些知名的代码库,而公司里所用的编译环境 ...

  4. oracle jdk1.7 内存,JDK 16 正式发布,一次性发布 17 个新特性…不服不行!

    上一篇:Java 15 正式发布, 14 个新特性 JDK 16 正式发布 牛逼啊,JDK 15 刚发布半年(2020/09/15),JDK 16 又如期而至(2021/03/16),老铁们,跟上. ...

  5. JDK 16 正式发布,一次性发布 17 个新特性,不服不行

    JDK 16 正式发布 牛逼啊,JDK 15 刚发布半年(2020/09/15),JDK 16 又如期而至(2021/03/16),老铁们,跟上. 来看下 Oracle Java 支持路线图: Ora ...

  6. JAVA17版本,JDK 16 正式发布,一次性发布 17 个新特性…不服不行!

    JDK 16 正式发布 牛逼啊,JDK 15 刚发布半年(2020/09/15),JDK 16 又如期而至(2021/03/16),老铁们,跟上. 来看下 Oracle Java 支持路线图: Ora ...

  7. 17个实用的JavaScript数组和对象的方法

    原文:Useful Javascript Array and Object Methods 作者:Robert Cooper 译者:Jim Xiao 前段时间,我收听了一个很棒的Syntax FM播客 ...

  8. Java基础学习总结(176)——JDK 16 正式发布,一次性发布 17 个新特性

    JDK 16 正式发布 JDK 16 不是一个长期支持的版本,只支持 6 个月到 2021 年 9 月,上一个长期支持版本还是 JDK 11,下一个长期支持版本是 JDK 17,还有半年也要发布了.所 ...

  9. Go1.17 这个新特性竟是 6 年前提出来的

    作者 | 站长polaris       责编 | 欧阳姝黎 Go1.17 预计在 8 月份发布.目前 tip.golang.org 可以浏览 Go1.17 的相关内容,https://tip.gol ...

  10. C++11\14\17\20 新特性整理

    文章目录 C++11 新特性 01 auto 与 decltype 02 defaulted 与 deleted 函数 03 final 与 override 04 尾置返回类型 05 右值引⽤ 06 ...

最新文章

  1. android圆形旋转菜单,而对于移动转换功能支持
  2. 化解谷歌AI霸权的另一种思路?开发平台的生态围剿
  3. 关于BeginPaint和WM_ERASEBKGND
  4. Draw Call未被批处理?在Unity 5.6中如何查找原因
  5. es6 Promise,生成器函数,async
  6. @param注解的用法解析_SpringBoot 配置类解析
  7. 【数据结构与算法】二叉树基本算法锦集
  8. 无法将类型int隐式转换为string_Scala implicit 隐式转换安全驾驶指南
  9. mysql数据修改-DEDE
  10. ultrascale和arm区别_[原创] Avnet Zynq UltraScale+MPSoC系列Ultra96开发方案
  11. jdk环境配置-windows 10
  12. 使用python+ffmpeg批量将ts文件转为mp4
  13. 小米云测平台远程真机调试使用教程
  14. Ubuntu 20.04 安装企业微信
  15. vue3 出现 Component inside <Transition> renders non-element root node that cannot be animated.
  16. 基于stm32f407的无线视屏传输项目
  17. 语音朗读html的源码,在网页上通过JS实现文本的语音朗读
  18. 互联网内容产业永远有机会
  19. 长沙计算机应届生工资水平,长沙毕业生期望的平均月薪是多少?答案在这里
  20. python redis使用

热门文章

  1. 用pathon实现计算器功能
  2. Eclipse \ MyEclipse \Scala IDEA for Eclipse里如何将控制台console输出的过程记录全程保存到指定的文本文件(图文详解)...
  3. HTML5 FormData实现文件上传实例
  4. TFS dataserver故障测试
  5. SpeedTree学习笔记(转)
  6. Symantec 11.0企业版安装与配置简介
  7. Tomcat优化之配置线程池高并发连接
  8. 34.Linux/Unix 系统编程手册(下) -- 进程组,会话和作业控制
  9. 10.Linux/Unix 系统编程手册(上) -- 时间
  10. 40. MySQL的权限与安全