悠悠楠杉
C++模板参数类型全解析:非类型参数与模板模板参数深度剖析
一、模板参数的类型体系
C++模板参数主要分为三大类型:
1. 类型参数(最常见形式)
2. 非类型参数(值参数)
3. 模板模板参数(高阶模板)
cpp
template</* 这里定义参数 */> class Widget;
1.1 类型参数(Type Parameters)
最基本的模板形式,使用typename
或class
关键字声明:
cpp
template<typename T>
void print(const T& val) { /*...*/ }
二、非类型参数详解
2.1 基本概念
非类型参数允许传递编译期常量值而非类型:cpp
template
class Buffer { /.../ };
template
class Logger { /.../ };
2.2 允许使用的类型(C++17标准)
- 整型及其衍生类型(
int
,long
,size_t
等) - 指针类型(包括函数指针)
- 左值引用类型
- 枚举类型
nullptr_t
(C++11起)- 包含
auto
的类型(C++17起)
典型应用场景:
cpp
template<size_t N>
struct Fibonacci {
static constexpr size_t value =
Fibonacci<N-1>::value + Fibonacci<N-2>::value;
};
2.3 底层实现原理
非类型参数会被编译器完全内联,生成的特化版本相当于硬编码值的独立类:
cpp
// 编译后会产生两个完全独立的类
Buffer<128> buf1; // 相当于 class Buffer_128 { ... };
Buffer<256> buf2; // 相当于 class Buffer_256 { ... };
三、模板模板参数精解
3.1 基本语法
允许模板参数本身是模板:
cpp
template<template<typename> class Container>
class Adapter {
Container<int> storage; // 实际使用时指定元素类型
};
3.2 典型应用模式
策略模板化:
cpp template<template<typename> class Allocator> class CustomVector { Allocator<int> alloc; // 可自由替换分配策略 };
容器无关算法:
cpp template<typename T, template<typename> class Sequence> void process(Sequence<T>& seq) { // 可处理任何符合接口的容器 }
3.3 C++17的改进
typename
关键字可以替代class
,提高一致性:
cpp
template<template<typename> typename Container>
class NewAdapter;
四、参数组合实战
4.1 混合参数模板
cpp
template<
typename T, // 类型参数
size_t Size, // 非类型参数
template<typename> class Allocator // 模板模板参数
>
class CustomArray {
Allocator<T> allocator;
T data[Size];
};
4.2 元编程示例
计算矩阵乘法的模板实现:
cpp
template<
size_t Rows,
size_t Cols,
template<size_t, size_t> class Matrix
>
auto multiply(Matrix<Rows, Cols>& a, Matrix<Cols, Rows>& b) {
// 编译期维度检查
}
五、最佳实践与陷阱
非类型参数限制:
- 浮点型(C++20前不可用)
- 类类型(C++20起部分支持)
- 运行时计算值(禁止使用)
模板模板参数匹配:cpp
// 定义时
template<template<typename, typename...> class Container>// 使用时
template>
class MyVector {...};性能考量:
- 非类型参数会导致代码膨胀
- 模板模板参数增加编译时间
六、现代C++演进
- C++11:支持非类型参数的
nullptr
- C++17:
auto
非类型参数、模板模板参数语法放宽 - C++20:浮点型非类型参数、类类型非类型参数
掌握这些高级模板技术,可以构建出既灵活又高性能的通用库,如STL中的std::array
(非类型参数)和Boost.MPL(模板模板参数)等著名实现。