【20天学C++】Day 18: C++14/17新特性
📅 学习时间:3-4小时
🎯 学习目标:掌握C++14/17实用新特性
💡 难度:★★★☆☆
1. C++14新特性
1.1 泛型Lambda
#include<iostream>#include<vector>#include<algorithm>usingnamespacestd;intmain(){// C++11: 必须指定类型autoadd11=[](inta,intb){returna+b;};// C++14: 泛型Lambdaautoadd14=[](autoa,autob){returna+b;};cout<<add14(1,2)<<endl;// intcout<<add14(1.5,2.5)<<endl;// doublecout<<add14(string("Hello, "),string("World"))<<endl;// string// 泛型排序vector<int>v={5,2,8,1,9};sort(v.begin(),v.end(),[](autoa,autob){returna>b;});return0;}1.2 返回类型推导
#include<iostream>usingnamespacestd;// C++14: 自动推导返回类型automultiply(inta,intb){returna*b;}// 递归时需要至少一个return在递归之前autofactorial(intn){if(n<=1)return1;returnn*factorial(n-1);}intmain(){cout<<multiply(3,4)<<endl;cout<<factorial(5)<<endl;return0;}1.3 变量模板
#include<iostream>usingnamespacestd;// 变量模板template<typenameT>constexprT pi=T(3.1415926535897932385);intmain(){cout<<pi<float><<endl;cout<<pi<double><<endl;return0;}1.4 make_unique
#include<iostream>#include<memory>usingnamespacestd;intmain(){// C++11: 只有make_sharedautosp=make_shared<int>(10);// C++14: 新增make_uniqueautoup=make_unique<int>(20);autoarr=make_unique<int[]>(5);return0;}2. C++17新特性
2.1 结构化绑定
#include<iostream>#include<tuple>#include<map>usingnamespacestd;tuple<int,string,double>getStudent(){return{1001,"张三",95.5};}intmain(){// 结构化绑定元组auto[id,name,score]=getStudent();cout<<id<<", "<<name<<", "<<score<<endl;// 结构化绑定数组intarr[]={1,2,3};auto[a,b,c]=arr;// 结构化绑定结构体structPoint{intx,y;};Point p{10,20};auto[x,y]=p;// 结构化绑定mapmap<string,int>m={{"a",1},{"b",2}};for(constauto&[key,value]:m){cout<<key<<": "<<value<<endl;}return0;}2.2 if/switch初始化
#include<iostream>#include<map>usingnamespacestd;intmain(){map<string,int>m={{"a",1},{"b",2}};// C++17: if语句中初始化if(autoit=m.find("a");it!=m.end()){cout<<"找到: "<<it->second<<endl;}else{cout<<"未找到"<<endl;}// it在这里已经失效// switch中初始化switch(intn=2;n){case1:cout<<"一"<<endl;break;case2:cout<<"二"<<endl;break;default:break;}return0;}2.3 std::optional
#include<iostream>#include<optional>#include<string>usingnamespacestd;optional<string>findName(intid){if(id==1)return"张三";if(id==2)return"李四";returnnullopt;// 表示没有值}intmain(){autoname1=findName(1);if(name1.has_value()){cout<<"找到: "<<name1.value()<<endl;}// 或者if(name1){cout<<"找到: "<<*name1<<endl;}autoname3=findName(3);cout<<name3.value_or("未知")<<endl;// 默认值return0;}2.4 std::variant
#include<iostream>#include<variant>#include<string>usingnamespacestd;intmain(){// 类型安全的unionvariant<int,double,string>v;v=10;cout<<get<int>(v)<<endl;v=3.14;cout<<get<double>(v)<<endl;v="hello";cout<<get<string>(v)<<endl;// 检查当前类型if(holds_alternative<string>(v)){cout<<"是string"<<endl;}// 访问者模式visit([](auto&&arg){cout<<"值: "<<arg<<endl;},v);return0;}2.5 std::any
#include<iostream>#include<any>#include<string>usingnamespacestd;intmain(){any a=10;cout<<any_cast<int>(a)<<endl;a=3.14;cout<<any_cast<double>(a)<<endl;a=string("hello");cout<<any_cast<string>(a)<<endl;// 检查类型if(a.type()==typeid(string)){cout<<"是string"<<endl;}// 错误转换会抛异常try{cout<<any_cast<int>(a)<<endl;}catch(constbad_any_cast&e){cout<<"类型错误: "<<e.what()<<endl;}return0;}2.6 std::string_view
#include<iostream>#include<string>#include<string_view>usingnamespacestd;// string_view不拥有字符串,只是视图voidprint(string_view sv){cout<<sv<<endl;}intmain(){string s="Hello World";constchar*cs="Hello C++";// 都可以传入print(s);print(cs);print("Hello Literal");// 子串不需要分配内存string_view sv=s;string_view sub=sv.substr(0,5);// 不分配新内存cout<<sub<<endl;return0;}2.7 折叠表达式
#include<iostream>usingnamespacestd;// 可变参数模板 + 折叠表达式template<typename...Args>autosum(Args...args){return(args+...);// 右折叠}template<typename...Args>voidprintAll(Args...args){(cout<<...<<args)<<endl;// 左折叠}intmain(){cout<<sum(1,2,3,4,5)<<endl;// 15cout<<sum(1.5,2.5,3.0)<<endl;// 7.0printAll("Hello"," ","World","!");// Hello World!return0;}2.8 内联变量
// 头文件中structConfig{staticinlineintvalue=42;// C++17: 可以在类内初始化};inlineintglobalValue=100;// 内联全局变量,多个编译单元只有一份2.9 if constexpr
#include<iostream>#include<type_traits>usingnamespacestd;template<typenameT>autogetValue(T t){ifconstexpr(is_integral_v<T>){returnt*2;}elseifconstexpr(is_floating_point_v<T>){returnt*0.5;}else{returnt;}}intmain(){cout<<getValue(10)<<endl;// 20cout<<getValue(3.14)<<endl;// 1.57cout<<getValue("hello")<<endl;// helloreturn0;}3. 小结
[C++14] 1. 泛型Lambda: [](auto a) 2. 返回类型推导 3. make_unique 4. 变量模板 [C++17] 5. 结构化绑定: auto [a, b] = ... 6. if/switch初始化 7. std::optional 8. std::variant 9. std::any 10. std::string_view 11. 折叠表达式 12. if constexpr 13. 内联变量下一篇预告:Day 19 - 多线程编程