跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++

C++11 新特性:可变参数模板、类功能、STL 变化与包装器

C++11 可变参数模板支持零个或多个参数,通过参数包和省略号实现泛型编程的数量变化。包扩展分为递归方式和函数参数展开方式,编译器在编译期完成实例化。emplace 系列接口允许在容器内原地构造对象,提升性能。新增类功能包括默认移动语义、成员变量默认值、default/delete 控制特殊成员函数以及 final/override 控制继承行为。包装器包含 function 和 bind,用于封装可调用对象。

片刻发布于 2026/3/27更新于 2026/10/2194 浏览
C++11 新特性:可变参数模板、类功能、STL 变化与包装器

可变参数模板

基本语法及原理

C++11 支持可变参数模板,即支持可变数量参数的函数模板和类模板。可变数目的参数称为参数包,存在两种参数包:模板参数包(表示零或多个模板参数)和函数参数包(表示零或多个函数参数)。

template <class ...Args> void Func(Args&&... args) {}

使用省略号来指出一个模板参数或函数参数表示一个包。在模板参数列表中,class... 或 typename... 指出接下来的参数表示零或多个类型列表;在函数参数列表中,类型名后面跟 ... 指出接下来表示零或多个形参对象列表。函数参数包可以用左值引用或右值引用表示,遵循引用折叠规则。 可变参数模板的原理本质还是去实例化对应类型和个数的多个函数。可以使用 sizeof... 运算符计算参数包中参数的个数。

template <class ...Args> void Print(Args&&... args) { cout << sizeof...(args) << endl; }
int main() {
    double x = 2.2;
    Print(); // 包里有 0 个参数
    Print(1); // 包里有 1 个参数
    Print(1, string("xxxxx")); // 包里有 2 个参数
    Print(1.1, string("xxxxx"), x); // 包里有 3 个参数
    return 0;
}

编译本质会结合引用折叠规则实例化出对应的函数。有了可变参数模板,我们在类型泛化基础上叠加数量变化,让泛型编程更灵活。

包扩展

对于参数包,除了计算参数个数,主要操作是扩展它。扩展一个包就是将它分解为构成的元素,对每个元素应用模式,获得扩展后的列表。通过在模式的右边放一个省略号 (...) 来触发扩展操作。 C++ 还支持更复杂的包扩展,直接将参数包依次展开作为实参给一个函数处理。 不支持用下面的方式去进行包扩展(运行时无法获取解析):

template <class ...Args> void Print(Args... args) {
    cout << sizeof...(args) << endl;
    for (size_t i = 0; i < sizeof...(args); i++) {
        cout << args[i] << " ";
    }
    cout << endl;
}

下面展示使用递归的一种包扩展方式。

方式一
void ShowList() {
    cout << endl;
}
template <class T, class ...Args> void ShowList(T x, Args... args) {
    cout << x << " ";
    ShowList(args...);
}
template <class ...Args> void Print(Args... args) {
    ShowList(args...);
}
int main() {
    Print(1, string("xxxxx"), 2.2);
    return 0;
}

编译器将可变参数模板通过模式的包扩展,推导出具体的重载函数。

方式二
template <class T> const T & GetArg(const T & x) {
    cout << x << " ";
    return x;
}
template <class ...Args> void Arguments(Args... args) { }
template <class ...Args> void Print(Args... args) {
    Arguments(GetArg(args)...);
}
int main() {
    Print(1, string("xxxxx"), 2.2);
    return 0;
}

编译器在编译时将函数模板扩展实例化为具体的函数调用。

emplace 系列接口

C++11 以后 STL 容器新增了 emplace 系列的接口,如 emplace_back 和 emplace。这些接口均为模板可变参数,功能上兼容 push 和 insert 系列,但是 emplace 还支持直接插入构造对象的参数,这样有些场景会更高效一些,可实现原地构造,避免临时对象拷贝。

新的类功能

默认的移动构造和移动赋值

成员变量声明时给缺省值

default 和 delete

final 与 override

STL 中一些变化

包装器

function

bind

目录

  1. 可变参数模板
  2. 基本语法及原理
  3. 包扩展
  4. 方式一
  5. 方式二
  6. emplace 系列接口
  7. 新的类功能
  8. 默认的移动构造和移动赋值
  9. 成员变量声明时给缺省值
  10. default 和 delete
  11. final 与 override
  12. STL 中一些变化
  13. 包装器
  14. function
  15. bind

更多推荐文章

查看全部
  • OpenClaw 多机器人协作方案:基于飞书构建智能体团队
  • 基于 Rokid CXR-M SDK 构建 AI 远程协作助手实战全记录
  • 手机检测系统上传失败重试机制与用户体验优化
  • Web Worker:前端多线程的隐形引擎
  • 前端状态管理进阶:Immutable.js 实战与避坑指南
  • Web-Check 本地部署与公网远程访问实战
  • VMware 虚拟机 CentOS 磁盘扩容实战:解决 growpart 报错与 LVM 调整
  • 命令行大模型交互工具 MCPHost 实战指南
  • Python 项目文件组织与工程化实践
  • Python + Neo4j 构建知识图谱入门教程
  • MHDDoS Python 网络压力测试工具架构解析
  • 本地部署大语言模型指南:使用 Ollama 运行开源模型
  • C++ AVL 树功能实现原理剖析
  • 人工智能大模型技术入门与核心原理解析
  • 自动化机器学习实战:从调参到模型部署指南
  • Android 获取 View 尺寸的三种常见方案
  • React Native 热更新方案:现状与选型分析
  • Python 纪念币预约自动化工具配置指南
  • Web-Rooter:基于 IR + Lint 的 AI Agent 联网执行方案
  • 电商 AI 绘画:产品提示词撰写实战指南

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online