广州企业自助建站/网站里的友情链接
模板与泛型编程
- 1. 定义模板
- 1.1 函数模板
- 2. 可变参数模板
1. 定义模板
1.1 函数模板
1.非类型模板参数
模板参数可以是类型,也可以是非类型,如整型、关联对象或函数类型的指针或左值引用。
模板参数是类型时,模板参数类型是typename或class。模板参数是非类型时,模板参数类型就是对应的模板参数的类型:整型、指针或引用。
template<typename T, size_t N>
void fun(T (&arr)[N]) { cout << N << endl; }
函数fun接受任何类型的数组名,都能输出数组长度。
数组长度不需要在调用时用尖括号给出,模板就能推断出数组长度。也就是说这样调用就可以fun(arr),而不需fun<10>(arr)。但数组长度外的其它非类型参数是需要在尖括号内给出的:
// 1. 模板函数。
// 整型
template<int n>
void fInteger1() { cout << n << endl; }
template<int n>
void fInteger2(int (&a)[n]) { cout << n << endl; }
// 指针。
template<int* p>
void fPointer() { cout << *p << endl; }
// 引用。
template<int (&r)[1]>
void fReference() { cout << r[0] << endl; }
// 函数指针。
template<void (*f)(int)>
void fFunpointer(int x) { f(x); }
// 2. 实参。
int a[3] = { 1, 2, 3 };
int p[1] = { 4 };
int r[1] = { 5};
void f(int x) { cout << x << endl; }
// 3. 测试。
int main() {fInteger1<3>(); // 给定模板参数。fInteger2(a); // 从实参推断模板参数。fPointer<p>(); // 给定模板参数。fReference<r>(); // 给定模板参数。fFunpointer<f>(6); // 给定模板参数。
}
2. 可变参数模板
1. 参数包
class Example { public: Example(int a, int b) { cout << a << " " << b << endl; } };
void print(int a, int b) { cout << a << " " << b << endl; }template<typename... Args>
void testArgsPkg(Args... args) {Example e = Example((args)...); // 1.参数包做初始化参数。print((args)...); // 2.参数包做函数参数。cout << sizeof...(args) << endl; // 3.输出参数包内参数个数而不是字节数。
}int main() {testArgsPkg(1, 3);
}
第 4 至 9 行定义了一个使用参数包的函数 testArgsPkg。可以向该函数传入任意个实参。