目录
函数模板基础
函数模板定义
函数模板实例
函数模板调用
函数模板本质
模板函数特化
模板参数限定
默认模板参数
多个模板参数
非类型模板参数
函数模板拓展
模板参数匹配规则
-
函数模板基础
-
函数模板定义
- 使用 template <typename T> 或 template <class T> 语法来声明函数模板,并在函数定义中使用模板参数。
-
template <typename T> T max(T a, T b) { return (a > b) ? a : b; }
-
函数模板实例
-
函数模板调用
- 一旦函数模板实例化完成,就可以像普通函数一样调用它。使用实际的参数来调用函数模板,并根据实参类型匹配合适的模板实例。
-
int main() { int result1 = max<int>(5, 3); // 显式实例化为max<int>(5, 3),返回5 int result2 = max(3, 5); // 自动类型推导为max<int>(3, 5),返回5 double result3 = max<double>(3.14, 2.71); // 显式实例化为max<double>(3.14, 2.71),返回3.14 double result4 = max(2.71, 3.14); // 自动类型推导为max<double>(2.71, 3.14),返回3.14 return 0; }
-
函数模板本质
-
int
-
-
-
float
-
-
-
-
模板函数特化
- 模板特化允许为特定的类型提供特殊的实现。可以为函数模板提供显式的特化版本,以处理特定类型的参数。
-
#include <iostream> template <typename T> T max(T num1, T num2) { return num1 > num2 ? num1 : num2; } //函数模板特化 template <> const char* max<const char*>(const char* str1, const char* str2) { return strlen(str1) > strlen(str2) ? str1 : str2; } int main() { auto ret1 = max(222, 111); //max<int>(222, 111); auto ret2 = max(3.14f, 6.66f); //max<float>(3.14f, 6.66f); auto ret3 = max("Hell", "World"); return 0; }
-
模板参数限定
-
#include <iostream> template <typename Type> Type Max(Type obj1, Type obj2) { static_assert(std::is_integral<Type>::value || std::is_floating_point<Type>::value , "Error Type CC"); return (obj1 > obj2) ? obj1 : obj2; } int main() { Max(111, 222); //Max<int> Max(111.111, 222.222); //Max<float> Max("Hell", "World"); return 0; }
-
-
默认模板参数
- 可以为函数模板的模板参数提供默认值,使得在使用函数模板时,如果没有显式提供模板参数,将使用默认值。
-
#include <iostream> // 带有默认模板参数的函数模板 template <typename T = int> void printValue(T value = 0) { std::cout << value << std::endl; } int main() { printValue(); // 使用默认模板参数 int,默认参数值为 0 printValue(5); // 使用默认模板参数 int,指定参数值为 5 printValue(3.14); // 推导为 double,默认参数值为 0.0 printValue("Hello"); // 推导为 const char*,默认参数值为 nullptr return 0; }
-
多个模板参数
- 函数模板可以有多个模板参数。可以使用逗号分隔的方式声明多个模板参数,并在函数定义中使用它们。
-
template <typename T, typename U> void printPair(T key, U value) { std::cout << "Key: " << key << ", Value: " << value << std::endl; }
-
非类型模板参数
- C++还支持非类型模板参数,允许在模板中使用非类型的值作为参数。
- 非类型模板参数可以是整数、指针、引用、枚举、指向成员的指针等。
-
#include <iostream> //多个模板参数 & 非类型模板参数 template <typename T, int N> T* CC_Alloc() { try { T* p = new T[N]; for (size_t i = 0; i < N; i++) { p[i] = 0; } return p; } catch (const std::exception& e) { //std::bad::alloc return NULL; } } int main() { auto* p = CC_Alloc<int, 5>(); return 0; }
-
-
函数模板拓展
-
模板参数匹配规则
-
当定义了多个模板参数则在函数内部必须使用否则编译器会报错
-
#include <iostream> template <typename T, typename N> T Fun(T t, T n) { return t; } int main() { //代码报错 -> 未使用 N Fun(1, 1); return 0; }
-
类型形式参数表中可以使用typename和class
-
#include <iostream> template <class T, class N> T Fun(T t, N n) { return t; } int main() { //代码报错 -> 未使用 N return 0; }
-
模板函数中参数不是基本类型时如果要想使用运算符操作需要类内部进行重载
-
#include <iostream> class Person { public: int m_Age; Person(int nAge): m_Age(nAge){} bool operator>(const Person& ref) { return this->m_Age > ref.m_Age ? true : false; } }; template <typename T> T Max(T param1, T param2) { return param1 > param2 ? param1 : param2; } int main() { Person p1(18); Person p2(28); auto p3 = Max(p1, p2); return 0; }
-
函数重载机制下的普通函数与模板函数调用顺序
-
#include <iostream> template <typename T> T Max(T param1, T param2) { std::cout << "模板函数被调用了\r\n"; return param1 > param2 ? param1 : param2; } int Max(int param1, int param2) { std::cout << "普通函数被调用了\r\n"; return param1 > param2 ? param1 : param2; } int main() { auto p1 = Max(1, 2); auto p2 = Max<int>(1, 2); return 0; }
-
函数模板的嵌套使用
#include <iostream> template <typename T> void OuterFunction(T value) { std::cout << "OuterFunction: " << value << std::endl; } template <typename T> void InnerFunction(T value) { std::cout << "InnerFunction: " << value << std::endl; } template <typename T> void NestedFunction(T value) { OuterFunction(value); InnerFunction(value); } int main() { int number = 42; NestedFunction(number); std::string text = "Hello"; NestedFunction(text); return 0; }
-
-