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 ,这位老兄特别健谈,一个人连续讲解了一个半小时没有休息,向他致敬!另外,由于本人最近手头事有点多,所以边写边更,速度慢请见谅!理解有误的地方也请各位同仁批评指正!
直接上代码,大家先有个直观感受
#include
#include
using namespace std;
int main()
{
pair p(3, 3.5); //now
cout << p.first << " " << p.second << endl;
pair p2(3, 3.5); //before
cout << p2.first << " " << p2.second << endl;
pair p3(3.5,"abc"); //now, 自动推导为 pair 类型
cout << p3.first << " " << p3.second << endl;
/*
p3.second.length(); //提示出错, gcc 7.1 的提示信息为:
[Error] request for member 'length' in 'p3.std::pair::second', which is of non-class type 'const char*'
*/
return 0;
}
可以看到,在以前,必须手动指定 pair 的模板参数。现在呢,可以通过你传进去的构造参数的类型自动推导生成的 pair 的类型了。不过要当心了,看那个 p3 ,第二个模板参数推导出的类型是 const char* ,不是 string !
当然,这种自动模板类型推导也适用于 vector , tuple (元组) 等其他容器,例如:
#include
#include
using namespace std;
int main()
{
vector v = {1.2, 5.6, 8.7};
for(const auto & ele : v) {
cout << ele << endl;
}
return 0;
}
记得以前学 C 语言时,要想让一个函数能返回两个值的话,用的是参数列表里传指针的形式;或者你自己再定义一个结构体也行。后来么,有了 C++ 里的 pair ,虽然理论上可以用这个返回两个参数,但是实际操作中用的还是不多。
当然了么,人心是贪婪的。既然能返回两个值,我肯定就会想着如何返回三个值 ~~~ 貌似用 tuple 里的 get<0>() get<1>() get<2>() 太烦了点。
而结构化绑定就是这样一种利器,能帮你更优雅的实现这些想法。
#include
#include
#include
using namespace std;
pair get_record()
{
return pair(0, "Jebediah");
}
auto get_record2() //这个函数的返回值类型声明利用了 C++14 中自动推导返回类型的特性, 等价于下面一个版本
{
return tuple(1, "Bill", "engineer");
}
/*
tuple 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
#include
#include
你可能要说了,C++11 里的 tie 也能完成这些功能啊。不好意思,Bryce 同志在他的幻灯片里罗列了一大堆 tie 的劣处:
/* 1 */
std::tuple t = // ...
double x, y, z;
std::tie(x, y, z) = t; // correct
/* 2 */
std::tuple t = // ...
double x, y, z;
std::tie(y, y, z) = t; // ^ UH-OH : no warning for repeated names.
/* 3 */
std::tuple t = // ...
double &x, &y, &z; // COMPILE ERROR
// Uninitialized refs.
std::tie(x, y, z) = t;
/* 4 */
std::tuple t = // ...
double const x, y, z;
std::tie(x, y, z) = t; // COMPILE ERROR
// Assignment to const.
而关于哪些类能用上结构化绑定的方式,以及怎么用,我不高兴打字了,直接上图吧:
3. 选择语句中的初始化器 (Selection Statements with Initializers)
顾名思义,就是现在能在 if 语句中做一些初始化工作了,上用法:
Syntax Equivalent To if (init; cond)
statement1;
else
statement2; {
init;
if (cond)
statement1;
else
statement2;
}
上样例:
#include
#include
#include
更多特性,未完待续。。。