原来 C++ 这么简单:每日十题轻松学 (Day 5 模板基础实战篇)

📘 本篇精准集中三大核心点:C++ 函数模板基本写法、类模板实战结构,以及模板实例化和编译特性分析。以实战为导向,涵盖常用写法、典型陷阱和底层原理,为后续掌握 STL 与泛型编程打下坚实基础。


🔁 Day 4 回顾

矩点记忆要点
虚函数运行时绑定,支持多态
vtable/vptr 机制基于虚表进行函数调用
切割/析构问题值传参分割字类、析构不虚导致泄露
RTTI/typeid运行时确认类型
dynamic_cast安全类型转换

🎯 今日目标:掌握模板机制的本质与实战技巧

  • 理解函数模板、类模板的语法和用途
  • 掌握模板实例化时机及编译器行为
  • 引入 SFINAE 基础、默认模板参数与特化概念
  • 为后续 STL 泛型开发和 C++20 concepts 做准备

🎓 核心知识点讲解

✅ 一、函数模板:一段代码打通多个类型

在这里插入图片描述

template<typename T>
T add(T a, T b) {
    return a + b;
}

使用:

add(3, 4);            // 推导为 int
add<double>(2.5, 1.7); // 显式指定为 double

📌 特点:

  • 编译期生成对应类型版本,提升代码复用性
  • 与内联优化结合后,效率极高
  • 推导失败时报错,能提供类型安全性

📌 常见陷阱:若传入不同类型,可能推导失败,需用 T1, T2 区分


✅ 二、类模板:为类型编写类的工厂

template<typename T>
class Box {
private:
    T value;
public:
    Box(T val) : value(val) {}
    T get() const { return value; }
    void set(T val) { value = val; }
};

使用:

Box<int> intBox(42);
intBox.set(55);
Box<std::string> strBox("hello");

📌 衍生能力:类模板可嵌套类/函数模板,也可使用默认参数和偏特化

📌 注意:成员函数通常写在头文件,因类模板编译时需全部可见


✅ 三、模板实例化规则:何时生成代码?

模板只在“使用时”实例化,否则不会报错:

template<typename T>
void risky() {
    int x = 1 / 0;  // 编译期不会报错,除非被调用
}

📌 特点:

  • 延迟实例化,减少不必要的报错与膨胀
  • 适用于条件编译、选择性启用逻辑(结合 SFINAE)

✅ 四、默认模板参数与类型别名(进阶起点)

template<typename T = int>
class Counter {
    T count = 0;
};

Counter<> c; // 实例化为 Counter<int>
// 类型萃取 + 别名简化
#include <type_traits>
template<typename T>
using remove_const_t = typename std::remove_const<T>::type;

📌 作用:提高模板可读性、减少冗长 typename 写法


✅ 五、SFINAE 简介:选择性启用的魔法

template<typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
process(T t) {
    std::cout << "int only: " << t << std::endl;
}

📌 含义:当条件满足时生成此函数,否则该重载被忽略(替代失败但不报错)

📌 用途:

  • 类型限制
  • 按不同类型定制行为(int/float/std::string)

🧪 实战练习:自定义泛型容器原型

任务:基于类模板 Box 实现以下功能:

  1. 增加 set() 方法重置值
  2. 增加 print() 方法:仅当 T 可用于 std::cout 时才可用

提示:使用 SFINAE 控制打印是否可见

template<typename T>
class Box {
    T value;
public:
    Box(T v) : value(v) {}
    T get() const { return value; }
    void set(T v) { value = v; }

    template<typename U = T>
    typename std::enable_if<std::is_same<decltype(std::cout << std::declval<U>()), std::ostream&>::value>::type
    print() const {
        std::cout << "Box: " << value << std::endl;
    }
};

🧩 总结

技术点价值与说明
函数模板通用算法实现,提高代码复用性
类模板泛型容器和工具类的构建基础
实例化机制控制生成,支持延迟逻辑与优化
SFINAE提供选择性重载,简化约束写法
默认模板参数提升接口友好性,减少使用者负担

📌 后续展开方向:

  • 模板特化与偏特化
  • C++20 Concepts 与 requires 表达式
  • STL 容器与算法源码解析
  • 编写类型安全的多态接口与策略类

你希望我继续撰写 Day 6 吗?或将前五天整理成博客合集/PDF 教程?我可以立即开始。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值