模板函数是C++泛型编程的核心工具,通过类型参数化实现代码复用:
// 声明
template<typename T>
T max(T a, T b);
// 定义
template<typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// 使用
int main() {
std::cout << max<int>(3, 5); // 显式实例化
std::cout << max(3.14, 2.71); // 隐式推导
}
// MathUtils.h
#pragma once
template
class Calculator {
public:
T add(T a, T b);
};
#include "MathUtils.inl" // 实现分离
// MathUtils.inl
#pragma once
template
T Calculator::add(T a, T b) {
return a + b;
}
// MathUtils.cpp
template class Calculator; // 显式实例化int版本
template class Calculator; // 显式实例化double版本
优势:
template
void printAll(Args&&... args) {
(std::cout << ... << args) << '\n'; // C++17折叠表达式
}
// 使用
printAll(1, "apple", 3.14); // 输出: 1apple3.14
template
std::unique_ptr createObject(Args&&... args) {
return std::make_unique(std::forward(args)...);
}
// 使用
auto obj = createObject(42, "test");
关键点:
std::forward
保持参数原始类型策略1:概念约束(C++20)
template
concept Addable = requires(T a, T b) {
{ a + b } -> std::same_as;
};
template
T sum(T a, T b) { return a + b; }
策略2:SFINAE控制
template>>
T sqrt(T value) {
return std::sqrt(value);
}
典型错误处理:
undefined reference to `void process(int)'
解决方案:
extern template
声明:// Header.h
extern template void process(int);
问题现象 | 原因分析 | 解决方案 |
---|---|---|
链接错误(undefined reference) | 模板定义未在调用处可见 | 将实现移到头文件或使用显式实例化 |
代码膨胀 | 过多隐式实例化 | 显式实例化常用类型 |
编译时间过长 | 模板展开复杂 | 使用外部模板(extern template ) |
类型约束错误 | 参数类型不满足要求 | 添加概念约束或SFINAE检查 |
.h
+ .inl
分离声明与实现extern template
减少重复实例化/**
* @brief 计算两个值的加权和
* @tparam T 必须支持+和*运算符的类型
* @param a 第一个值
* @param b 第二个值
* @param weight 权重系数(0-1)
* @return 加权计算结果
*/
template
T weightedSum(T a, T b, double weight) {
return a * weight + b * (1 - weight);
}
https://github.com/0voice