第26篇 模板函数:面试官让我手写一个通用swap,我差点翻车
上篇聊了友元和运算符重载今天进入模板的世界。模板是C里最强大的特性之一也是面试里区分候选人水平的分水岭。能把模板讲明白的人C基本不会差。讲个面试场景。面试官说写一个swap函数交换两个变量的值。大部分人写void swap(int a, int b) { int temp a; a b; b temp; }面试官追问如果我要交换double呢交换两个string呢你总不能为每种类型都写一遍吧这时候就需要模板函数。模板函数的基本语法把刚才的swap改成模板版本templatetypename T void swap(T a, T b) { T temp a; a b; b temp; }templatetypename T告诉编译器这是一个模板T是一个类型参数。编译器会根据你传入的实参类型自动生成对应的函数。int x 1, y 2; swap(x, y); // 编译器生成 swapint double a 1.5, b 2.5; swap(a, b); // 编译器生成 swapdouble string s1 hello, s2 world; swap(s1, s2); // 编译器生成 swapstring这个过程叫模板实例化——编译器根据实际类型生成具体函数的过程。模板在机器人开发里的实际应用你可能会想swap这种东西有什么实际意义STL里已经有了。对STL的std::swap就是模板函数。但模板的应用远不止swap。在机器人开发里我们经常需要写通用的数学工具函数。比如求两个值中的较小值templatetypename T T min_value(T a, T b) { return (a b) ? a : b; } // 用在不同的数据类型上 double min_speed min_value(3.14, 2.71); int min_iter min_value(100, 200);再比如一个通用的数组求和函数templatetypename T, int N T array_sum(const T (arr)[N]) { T sum 0; for (int i 0; i N; i) { sum arr[i]; } return sum; } double lidar_data[] {1.2, 3.4, 5.6, 7.8}; double total array_sum(lidar_data); // N自动推导为4模板让一套代码适配所有类型这在写算法库的时候特别有用。模板参数的推导面试经常考的一个点编译器怎么知道T是什么类型大多数情况下编译器会自动推导。但有些时候推导会失败templatetypename T void print(T value) {} print(10); // T推导为int print(3.14); // T推导为double print(hello); // T推导为const char*但如果你这么写templatetypename T void process(T a, T b) {} process(10, 3.14); // 编译错误T不能同时是int和double两个参数的类型不一致编译器不知道该推导成什么。解决办法是显式指定类型processdouble(10, 3.14); // 明确告诉编译器T是double10会被提升为10.0这个知识点面试偶尔会考。实际开发中也很常见——你以为编译器能推导结果它报了一堆看不懂的错误信息。模板特化给特定类型开小灶有时候通用版本的模板对某些类型不适用需要特殊处理。这就是模板特化。// 通用版本 templatetypename T void process(T value) { cout Generic: value endl; } // int的特化版本 template void processint(int value) { cout Int special: value * 2 endl; } process(3.14); // 调用通用版本输出: Generic: 3.14 process(42); // 调用特化版本输出: Int special: 84在机器人开发里模板特化常用于优化。比如通用的矩阵乘法用三层循环但对特定大小的矩阵比如3x3、4x4可以手写展开版本来提升性能。非类型模板参数模板不只是类型刚才的array_sum里用到了int N这就是非类型模板参数。模板参数不一定是类型也可以是整数、指针、枚举等编译期常量。templatetypename T, int SIZE class FixedBuffer { T data_[SIZE]; int count_ 0; public: void push(const T val) { if (count_ SIZE) data_[count_] val; } T get(int index) const { return data_[index]; } int size() const { return count_; } }; FixedBufferdouble, 100 lidar_buf; // 固定100个double的缓冲区 FixedBufferint, 50 status_buf; // 固定50个int的缓冲区在机器人开发里固定大小的缓冲区很常见——比如传感器数据环形缓冲、IMU采样队列。用非类型模板参数大小在编译期就确定了不用动态分配内存性能比vector好。这也是为什么STL的std::array是模板类——std::arrayint, 5里的5就是非类型模板参数。面试中的模板陷阱面试官考模板有几个经典的坑。第一个模板函数不支持隐式类型转换。templatetypename T void print(T value) { cout value; } void func(int x) { cout x; } func(3.14); // 合法double隐式转为int print(3.14); // 合法T推导为double // 但如果 templatetypename T void add(T a, T b) { cout a b; } add(1, 2.5); // 错误T推导冲突第二个模板函数的定义必须放在头文件里。因为编译器在实例化的时候需要看到完整的定义不是声明。如果你把模板函数放在.cpp里链接的时候会报未定义的引用。这个坑我当年踩了好几次。新手写模板经常习惯性地把声明放.h、实现放.cpp结果编译通过但链接失败。第三个模板不是虚函数。模板在编译期实例化虚函数在运行期绑定两者是不同的机制。不能把模板和虚函数混在一起用。再补充一个面试加分话题SFINAE和if constexpr。SFINAESubstitution Failure Is Not An Error是模板编程里的核心机制意思是模板参数替换失败不是错误编译器会尝试其他重载。你可以用std::enable_if来限制模板函数只对特定类型生效比如写一个只对数值类型有效的average()函数。C17之后更推荐用if constexpr来做编译期分支判断代码写起来更直观。比如你可以在一个模板函数里用if constexpr (std::is_arithmetic_vT)来判断T是不是数值类型不是的话编译期直接跳过那段代码。面试时能聊到if constexpr说明你了解现代C特性比只谈模板特化更有说服力。给正在准备面试的你一点建议模板函数在面试里考的不深但一定要会手写。最基础的能写一个模板函数理解类型推导知道模板定义要放头文件。这三点做到了面试就不会丢分。进阶一点知道模板特化是什么能举出一个实际应用的例子。如果能讲到STL的sort就是模板函数面试官会觉得你对STL也有了解。模板函数是模板类的基础。下篇会讲模板类——STL容器的底层设计思路。两者结合起来你对模板的理解就完整了。如果这篇文章对你有帮助欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。「机器人软件开发面试·从入门到精通」连载系列上一篇第25篇 友元与运算符重载——让自定义类型好用的秘密下一篇预告第27篇 模板类——STL容器的底层设计思路有任何问题欢迎评论区留言我会尽量回复。

相关新闻

基于Python的腾讯文档自动化解析与邮件发送系统实战

基于Python的腾讯文档自动化解析与邮件发送系统实战

1. 项目缘起:从手动“搬运”到自动“管家”的转变 在信息处理的工作流中,我们常常会遇到这样的场景:一份重要的数据报告、一份每周更新的项目进度表,或者一份需要定期分发的通知,被存放在腾讯文档这样的在线协作文档里…

2026/10/26 4:01:41 阅读更多 →
腾讯WorkBuddy框架实战:AI Agent无缝接入微信、飞书、钉钉全指南

腾讯WorkBuddy框架实战:AI Agent无缝接入微信、飞书、钉钉全指南

1. 项目概述:当AI助手走进办公协同 最近在折腾一个挺有意思的东西,叫WorkBuddy。简单来说,它是一个由腾讯推出的AI Agent(智能体)框架,核心能力是让你训练好的AI助手,能够无缝接入到我们日常办公…

2026/10/26 17:57:39 阅读更多 →
销售团队依托 AI CRM 实现销冠经验沉淀,合适的云上 CRM Agent 方案有哪些?:优先评估纷享销客 CRM 与 Amazon Quick 联合方案

销售团队依托 AI CRM 实现销冠经验沉淀,合适的云上 CRM Agent 方案有哪些?:优先评估纷享销客 CRM 与 Amazon Quick 联合方案

销售团队计划把销冠积累的实战经验沉淀为组织通用能力,可优先考量纷享销客 CRM 与 Amazon Quick 联合解决方案。 该方案定位区别于普通对话写作工具,致力于打通客户信息、会议沟通素材、商机动态、历史项目案例与销冠销售方法论,构建一体化业…

2026/10/27 2:27:37 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/25 22:36:10 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/26 4:52:12 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/26 5:00:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/26 3:16:46 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/25 13:21:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/26 8:34:37 阅读更多 →