C++ 作为一门兼顾底层控制与高层抽象的语言,其模板机制是泛型编程(Generic Programming)和元编程(Metaprogramming)的核心工具。模板的引入使得代码更加灵活、复用性更强,同时也能实现编译期计算等高级特性。
模板是现代 C++ 的基石之一,被广泛应用于标准库、STL 容器、算法库、Boost、甚至各种高性能计算框架中。本文将从模板基础讲起,逐步深入函数模板、类模板、模板特化、SFINAE、constexpr 和模板元编程等进阶内容,并通过实例帮助你全面掌握这一强大机制。
模板是 C++ 中的一种机制,用于编写与类型无关的代码。常见形式有:
cpp复制编辑template<typename T>
T add(T a, T b) {
return a + b;
}
intmain() {
std::cout << add(1, 2) << std::endl; // 输出 3
std::cout << add(1.5, 2.3) << std::endl; // 输出 3.8
}
模板函数根据参数类型自动推导 T
。
cpp复制编辑template<typename T>
classBox {
T value;
public:
Box(T val) : value(val) {}
T get()const { return value; }
};
使用:
cpp复制编辑Box<int> b(42);
std::cout << b.get() << std::endl;
cpp复制编辑template<typename T = int>
class DefaultBox {
T value;
public:
DefaultBox(T val) : value(val) {}
T get() { return value; }
};
cpp复制编辑template<typename T>
classPrinter;
template<>
classPrinter<int> {
public:
voidprint() { std::cout << "int specialization\n"; }
};
cpp复制编辑template<typename T, typename U>
classPair;
template<typename T>
classPair<T, int> {
public:
voidprint() { std::cout << "Partial specialization with int\n"; }
};
函数模板配合 auto
使用可以增强简洁性:
cpp复制编辑template<typename T, typename U>
automultiply(T a, U b) {
return a * b;
}
cpp复制编辑template<int N>
structFactorial {
staticconstint value = N * Factorial<N - 1>::value;
};
template<>
structFactorial<0> {
staticconstint value = 1;
};
使用:
cpp复制编辑int x = Factorial<5>::value; // 120
SFINAE(Substitution Failure Is Not An Error)机制允许模板推导失败时不导致编译错误,而是选择其他候选模板。
cpp复制编辑template<typename T>
autotest(T t) -> decltype(t.begin(), void(), std::true_type{}) {
return std::true_type{};
}
template<typename T>
std::false_type test(...) {
return std::false_type{};
}
判断某个类型是否有 begin()
方法。
std::enable_if
cpp复制编辑template<typename T>
typenamestd::enable_if<std::is_integral<T>::value>::type
onlyIntegral(T t) {
std::cout << "Integer only\n";
}
C++11 引入 constexpr
使函数可以在编译期求值。
cpp复制编辑constexprintsquare(int x) {
return x * x;
}
constexprint value = square(10);
与模板配合,可构建更强大的编译期表达式系统。
cpp复制编辑template<typename T>
voidprint(T value) {
std::cout << value << " ";
}
template<typename T, typename... Args>
voidprint(T first, Args... rest) {
std::cout << first << " ";
print(rest...);
}
递归打印任意数量参数。
cpp复制编辑template<typename... Args>
autosum(Args... args) {
return (... + args); // 左折叠
}
cpp复制编辑template<bool cond, typename T, typename U>
structConditional {
using type = T;
};
template<typename T, typename U>
structConditional<false, T, U> {
using type = U;
};
使用:
cpp复制编辑using Type = Conditional<true, int, double>::type; // int
cpp复制编辑template<typename T, typename U>
structIsSame {
staticconstbool value = false;
};
template<typename T>
structIsSame<T, T> {
staticconstbool value = true;
};
cpp复制编辑template<typename T, typename Allocator = std::allocator<T>>
class vector;
支持任意类型存储。
cpp复制编辑template<class InputIt, class UnaryFunction>
UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f);
场景 | 技术 |
---|---|
泛型容器设计 | 类模板 |
算法复用 | 函数模板 |
高性能计算 | constexpr + 模板递归 |
类型校验 | SFINAE + enable_if |
编译期配置 | 模板特化 |
concepts
:用于限制模板参数的合法类型requires
:表达式约束template parameter lists
改进示例:
cpp复制编辑template<typename T>
concept Integral = std::is_integral_v<T>;
template<Integral T>
T add(T a, T b) {
return a + b;
}
模板编程在 C++ 中的重要性不言而喻,它不仅为泛型编程提供了机制,还拓展了编译期逻辑计算的能力。从基础模板到复杂元编程结构,模板是构建高效、灵活、可维护代码的核心力量。
关键回顾:
enable_if
用法
文章评论(0条评论)
登录后参与讨论