新闻详情

新闻详情

首页 / 资讯中心 / 详情

【C++】14. C++11新特性【下】

发布时间:2026/10/2 12:55:06来源:尧图网络
【C++】14. C++11新特性【下】
目录四、可变参数模版1. 概念及简单定义2.参数包展开五、emplace系列接口六、函数包装器1.function2.bind四、可变参数模版1. 概念及简单定义所谓可变参数模板就是允许一个模板接收任意数量的模板参数。最基本的写法如下templateclass... Args void ShowList(Args... args) { }class... Args表示声明了一个模板参数包。这里的Args 并不是一个普通的模板参数而是一组模板参数。也就是说普通模板可能是templateclass T这里的T只表示一个类型。而templateclass... Args 中的Args可以表示0 个类型 1 个类型 2 个类型 3 个类型 …… N 个类型因此称为模板参数包。再来看Args... args这里的args称为函数参数包。Args 保存一组类型args 保存与这些类型对应的一组实际参数因此可变参数模板不仅意味着参数数量可以变化。还意味着每个参数的类型也可以不同。这也是可变参数模板非常强大的地方。可用sizeof...计算参数包中到底有多少个参数templateclass... Args void Func(Args... args) { cout sizeof...(Args) endl; cout sizeof...(args) endl; }2.参数包展开参数包代表的是“一组参数”不能直接把整个参数包当成一个普通对象使用。所以这样是不对的templateclass... Args void ShowList(Args... args) { cout args endl; }所以如果想分别处理参数包中的每一个参数就需要想办法将参数args一个个拿出来这个过程就叫参数包展开。#include iostream using namespace std; // 递归终止函数 void ShowList() { cout endl; } // 展开函数 templateclass T, class... Args void ShowList(T value, Args... args) { cout value ; ShowList(args...); } int main() { ShowList(); ShowList(1); ShowList(1, 2); ShowList(1, 2, 3); ShowList(1, 2, 3, 4); return 0; }重点看函数参数T value, Args... args可以把它理解成两部分T value接收当前参数列表中的第一个参数Args... args接收剩余的所有参数。也就是说每调用一次函数都会先从当前参数中取出第一个参数交给value处理再把后面的参数保存在args...中。处理完当前的value后再通过ShowList(args...);递归处理剩余参数。于是整个参数包就会被一个一个展开直到没有参数为止。因此递归展开参数包的核心思想就是每次取出第一个参数进行处理再把剩余参数继续交给下一次递归调用。可变参数模板的参数类型可以完全不同五、emplace系列接口C11新增的emplace系列接口就是一个非常典型的应用。在 C11 之前我们向容器尾部插入元素经常使用push_back()现在可以使用更高效的emplace_back()了listDate lt; lt.push_back(Date(2025, 7, 18)); lt.emplace_back(2025, 7, 18);class Date { public: Date(int year 1, int month 1, int day 1) :_year(year) , _month(month) , _day(day) { cout Date构造函数 endl; } Date(const Date d) :_year(d._year) , _month(d._month) , _day(d._day) { cout Date拷贝构造 endl; } private: int _year; int _month; int _day; }; int main() { listDate lt; lt.emplace_back(2026, 1, 2); cout endl; lt.push_back(Date(2026, 1, 2)); return 0; }当节点存储浅拷贝类型时emplace_back仅调用一次构造函数而push_back需要调用一次构造函数和一次拷贝构造。因此对于此类类型emplace_back的开销更小。六、函数包装器C11引入了函数包装器他可以封装函数方便调用不同的函数。1.functionfunction的本质是一个类模版实例出的对象可以存储其他调用对象头文件是functional#include iostream #include functional using namespace std; //函数 int f1(int a, int b) { return a b; } //仿函数 struct F2 { int operator()(int a, int b) { return a - b; } }f2; //lambda表达式 auto f3 [](int a, int b)-int{ return a * b; }; int main() { functionint(int, int) f; f f1; cout f(8, 10) endl; f f2; cout f(8, 10) endl; f f3; cout f(8, 10) endl; return 0; }定义function时注意要显式实例化要接收对象的参数和返回值调用时直接用函数调用的方式进行传参。注意用function包装非静态成员函数时别忘记第一个参数是this指针显式实例化时要将对象指针类型写在参数列表中class Student { public: Student(string name, int no) :_name(name) , _no(no) { } void Print() const { cout _name _no endl; } static int add(int x, int y) { cout static_add ; return x y; } private: string _name; int _no; }; int main() { functionvoid(Student*) Func1 Student::Print; //包装类内成员函数(内部走-*) functionvoid(Student) Func2 Student::Print; //包装类内成员函数(内部走.*) functionint(int, int) Func3 Student::add; //包装类内静态成员函数 int x 1, y 10; Student s1 { guoshi, 20260101 }; Func1(s1); Func2(s1); cout Func3(x, y) endl; return 0; }2.bindbind 是一个函数模板头文件functional它接收一个可调用对象和一组参数返回一个新的可调用对象——新对象可以调整原函数的传参顺序、给任意位置预置固定的值也可以把成员函数的对象绑死。#include iostream #include functional using namespace std; using namespace std::placeholders; // _1 _2 _3 ... 都在这个空间里 void Print(int a, int b, int c) { cout a b c endl; } int main() { auto f bind(Print, _1, _2, _3); // 包装 Print 函数 f(1, 2, 3); return 0; }运行结果1 2 3三个要点bind 的第一个参数是被包装的可调用对象后面的位置才是参数_1 _2 _3是占位符表示调用时传入的第 1、2、3 个实参——它跟函数的第几个参数没有关系bind 的返回类型是编译器生成的、手写不出来的类型所以要用auto接收占位符也可以按需一个个展开不必整个空间都放开using std::placeholders::_1; using std::placeholders::_2; using std::placeholders::_3;占位符的排放顺序就是实参交给原函数的顺序int main() { auto f bind(Print, _1, _3, _2); // 把第 2、3 个位置的代号换一下 f(10, 20, 30); return 0; } 运行结果10 30 20也可以给任意位置预置固定的值int main() { auto f bind(Print, _1, 100, _2); // 中间那个参数固定成 100 f(7, 8); return 0; } 7 100 8
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

用GPT-6从零到上线:完整实操一个可访问网站的全过程 2026/10/2 15:26:25

用GPT-6从零到上线:完整实操一个可访问网站的全过程

GPT-6的API申请通过那天,我其实没急着去玩那些花哨的玩法。画电路图、写剧本、生成Excel公式,这些我在社交时间线上已经见烦了。我更关心一件特别朴素的事:拿GPT-6给我做一个能用的网站,从环境安装开始,一直到部署上线…

阅读更多 →
LTE抓包分析指南:从接口选型到信令定位 2026/10/2 15:26:24

LTE抓包分析指南:从接口选型到信令定位

简介:《LTE 抓包分析指导手册》是面向通信工程师、网络优化与运维人员的一份实战指南,围绕LTE网络数据包捕获与分析展开,帮助读者定位UU口、ENB和核心网侧的通信异常,排查丢包、乱序等问题,适用于日常维护、现场测试和…

阅读更多 →
Agent生产落地四道坎:工具调用、Schema、可观测性与并发架构实战 2026/10/2 15:26:24

Agent生产落地四道坎:工具调用、Schema、可观测性与并发架构实战

1. 从 Demo 到生产:Agent 落地为什么总在同一个地方翻车做过 Agent 项目的人大概都有过这种体验:本地跑 Demo 的时候,工具调用丝滑、推理链路清晰、输出结果惊艳,给老板演示完信心满满。结果一上生产环境,用户量稍微起…

阅读更多 →
VSG虚拟同步发电机控制原理与光伏并网Matlab仿真建模详解 2026/10/2 15:26:23

VSG虚拟同步发电机控制原理与光伏并网Matlab仿真建模详解

光伏并网这块,早期大家做仿真基本都绕不开 PQ 控制和 droop 控制。PQ 控制简单粗暴,有功无功解耦,并网稳定,但说白了它就是个“跟屁虫”,电网电压稍微晃一下,逆变器就懵了,既没有惯量也不参与调…

阅读更多 →
ClinePass 底层技术全解:多模型统一网关、高倍率限流与 Agent 编程工作流实现原理 2026/10/2 15:26:21

ClinePass 底层技术全解:多模型统一网关、高倍率限流与 Agent 编程工作流实现原理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
C#实现SSE通信方式的MCP Server:把endpoint改到TaoToken的完整配置与验证 2026/10/2 15:26:09

C#实现SSE通信方式的MCP Server:把endpoint改到TaoToken的完整配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉