C++模板进阶技巧全解析

  1. 模板特化

模板特化允许为特定类型提供定制化的实现。

  • 全特化:为所有模板参数指定具体类型。
cpp 复制代码
template <typename T>
class MyClass {
public:
    void print() { std::[](https://en.cppreference.com/w/cpp/io/c) << "Generic type\n"; }
};

// 全特化版本
template <>
class MyClass<int> {
public:
    void print() { std::[](https://en.cppreference.com/w/cpp/io/c) << "Specialized for int\n"; }
};
  • 偏特化:为部分模板参数指定类型或约束。
cpp 复制代码
template <typename T1, typename T2>
class MyPair { /*...*/ };

// 偏特化:当两个类型相同时
template <typename T>
class MyPair<T, T> { /*...*/ };

2. 可变参数模板

允许模板接受任意数量的参数,使用...语法。

cpp 复制代码
template <typename... Args>
void printAll(Args... args) {
    (std::[](https://en.cppreference.com/w/cpp/io/c) << ... << args) << '\n'; // 折叠表达式(C++17)
}

// 递归展开示例
template <typename T>
void print(T t) {
    std::[](https://en.cppreference.com/w/cpp/io/c) << t << ' ';
}

template <typename T, typename... Args>
void print(T t, Args... args) {
    print(t);
    print(args...); // 递归调用
}

3. 模板元编程

在编译期执行计算,利用模板实例化机制。

cpp 复制代码
// 编译期计算阶乘
template <int N>
struct Factorial {
    static const int value = N * Factorial<N - 1>::value;
};

template <>
struct Factorial<0> {
    static const int value = 1;
};

// 使用
int main() {
    std::[](https://en.cppreference.com/w/cpp/io/c) << Factorial<5>::value; // 输出120
}

4. SFINAE

"替换失败不是错误",用于约束模板的有效性。

cpp 复制代码
#include <type_traits>

template <typename T>
auto foo(T t) -> std::enable_if_t<std::is_integral_v<T>, void> {
    std::[](https://en.cppreference.com/w/cpp/io/c) << "Integral type\n";
}

template <typename T>
auto foo(T t) -> std::enable_if_t<!std::is_integral_v<T>, void> {
    std::[](https://en.cppreference.com/w/cpp/io/c) << "Non-integral type\n";
}

5. 概念约束 (C++20)

使用conceptrequires明确模板参数要求。

cpp 复制代码
template <typename T>
concept Addable = requires(T a, T b) {
    { a + b } -> std::convertible_to<T>;
};

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

6. 模板与完美转发

结合万能引用std::forward实现参数高效传递。

cpp 复制代码
template <typename... Args>
void wrapper(Args&&... args) {
    target(std::forward<Args>(args)...);
}

注意事项

  1. 模板错误信息通常冗长复杂,需耐心分析
  2. 避免过度使用模板元编程导致编译时间过长
  3. 明确typenametemplate在依赖类型中的使用场景
相关推荐
折哥的程序人生 · 物流技术专研4 小时前
Java面试85题图解版 · 特别篇:2026后端高频面试题复盘(算法底层逻辑+高并发架构设计全解析,附Java实战代码)
java·网络·数据库·算法·面试
xxie1237944 小时前
return与print
开发语言·python
秋94 小时前
从 Python 后端工程师转型 AI Engineer(AI 工程化)的完整补课清单(2026实战版)
开发语言·人工智能·python
一条泥憨鱼4 小时前
【Redis】数据类型和常用命令
java·数据库·redis·后端·缓存
云烟成雨TD5 小时前
Spring AI Alibaba 1.x 系列【78】沙箱(Sandbox)
java·人工智能·spring
程序员二叉5 小时前
【Java】 异常高频面试题精讲 | 易错点+对比总结
java·开发语言·面试
周航宇JoeZhou5 小时前
JB3-9-SpringAI(二)
java·ai·agent·多智能体·调度·智能体·观察
好家伙VCC5 小时前
Web Components主题热切换方案揭秘
java·前端
慕木沐5 小时前
Google ADK Java 1.0版本 核心机制与实战 Demo
java·开发语言·python
Roann_seo%5 小时前
C++文件操作完全指南:从文本读写到二进制文件处理
开发语言·c++