- 模板特化
模板特化允许为特定类型提供定制化的实现。
- 全特化:为所有模板参数指定具体类型。
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)
使用concept和requires明确模板参数要求。
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)...);
}
注意事项
- 模板错误信息通常冗长复杂,需耐心分析
- 避免过度使用模板元编程导致编译时间过长
- 明确
typename和template在依赖类型中的使用场景