C/C++ - 函数模板

目录

函数模板基础

函数模板定义

函数模板实例

函数模板调用

函数模板本质

模板函数特化

模板参数限定

默认模板参数

多个模板参数

非类型模板参数

函数模板拓展

模板参数匹配规则


  • 函数模板基础

    • 函数模板定义

      • 使用 template ​​​​​ 或 template ​​​​​ 语法来声明函数模板,并在函数定义中使用模板参数。
      • template 
        T max(T a, T b) {
            return (a > b) ? a : b;
        }
        
    • 函数模板实例

      • 在使用函数模板之前,需要进行模板实例化,将模板参数替换为具体的类型。实例化可以通过显式指定模板参数或使用自动类型推导来完成。
      • 显式实例化:可以使用<类型>​​​​的语法显式指定模板参数。例如,max(5, 3)​​​​实例化了max​​​​函数模板为类型参数为int​​​​的版本。
      • 自动类型推导:C++11引入了自动类型推导,允许编译器根据函数实参的类型推导出模板参数的类型。例如,max(5, 3)​​​​可以自动推导为max(5, 3)​​​​。
    • 函数模板调用

      • 一旦函数模板实例化完成,就可以像普通函数一样调用它。使用实际的参数来调用函数模板,并根据实参类型匹配合适的模板实例。
      • int main() 
        {
            int result1 = max(5, 3);  // 显式实例化为max(5, 3),返回5
            int result2 = max(3, 5);       // 自动类型推导为max(3, 5),返回5
        
            double result3 = max(3.14, 2.71);  // 显式实例化为max(3.14, 2.71),返回3.14
            double result4 = max(2.71, 3.14);           // 自动类型推导为max(2.71, 3.14),返回3.14
        
            return 0;
        }
        
    • 函数模板本质

      • int

        • C/C++ - 函数模板_第1张图片​​
        • C/C++ - 函数模板_第2张图片​​
      • float

        • C/C++ - 函数模板_第3张图片​​
        • C/C++ - 函数模板_第4张图片​​
    • 模板函数特化

      • 模板特化允许为特定的类型提供特殊的实现。可以为函数模板提供显式的特化版本,以处理特定类型的参数。
      • #include 
        
        template 
        T max(T num1, T num2)
        {
        	return num1 > num2 ? num1 : num2;
        }
        
        //函数模板特化
        template <>
        const char* max(const char* str1, const char* str2)
        {
        	return strlen(str1) > strlen(str2) ? str1 : str2;
        }
        
        int main()
        {
        	auto ret1 = max(222, 111);		//max(222, 111);
        	auto ret2 = max(3.14f, 6.66f);	//max(3.14f, 6.66f);
        	auto ret3 = max("Hell", "World");
        
        	return 0;
        }
        
    • 模板参数限定

      • #include 
        
        template 
        Type Max(Type obj1, Type obj2)
        {
        	static_assert(std::is_integral::value || std::is_floating_point::value , "Error Type CC");
        	return (obj1 > obj2) ? obj1 : obj2;
        }
        
        int main()
        {
        	Max(111, 222);				//Max
        	Max(111.111, 222.222);		//Max
        	Max("Hell", "World");
        
        	return 0;
        }
        
    • 默认模板参数

      • 可以为函数模板的模板参数提供默认值,使得在使用函数模板时,如果没有显式提供模板参数,将使用默认值。
      • #include 
        
        // 带有默认模板参数的函数模板
        template 
        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 
        void printPair(T key, U value) 
        {
            std::cout << "Key: " << key << ", Value: " << value << std::endl;
        }
        
    • 非类型模板参数

      • C++还支持非类型模板参数,允许在模板中使用非类型的值作为参数。
      • 非类型模板参数可以是整数、指针、引用、枚举、指向成员的指针等。
      • #include 
        
        //多个模板参数 & 非类型模板参数
        template 
        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();
        
        	return 0;
        }
        
  • 函数模板拓展

    • 模板参数匹配规则

      • 当定义了多个模板参数则在函数内部必须使用否则编译器会报错

      • #include 
        
        template 
        T Fun(T t, T n)
        {
        	return t;
        }
        
        int main()
        {
        	//代码报错 -> 未使用 N
        	Fun(1, 1);
        
        	return 0;
        }
        
      • 类型形式参数表中可以使用typename​​​和class​​​

      • #include 
        
        template 
        T Fun(T t, N n)
        {
        	return t;
        }
        
        int main()
        {
        	//代码报错 -> 未使用 N
        
        	return 0;
        }
        
      • 模板函数中参数不是基本类型时如果要想使用运算符操作需要类内部进行重载

      • #include 
        
        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 
        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 
        
        template 
        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(1, 2);
        
        	return 0;
        }
        
      • 函数模板的嵌套使用

        #include 
        
        template 
        void OuterFunction(T value) {
            std::cout << "OuterFunction: " << value << std::endl;
        }
        
        template 
        void InnerFunction(T value) {
            std::cout << "InnerFunction: " << value << std::endl;
        }
        
        template 
        void NestedFunction(T value) {
            OuterFunction(value);
            InnerFunction(value);
        }
        
        int main() {
            int number = 42;
            NestedFunction(number);
        
            std::string text = "Hello";
            NestedFunction(text);
        
            return 0;
        }
        

 

你可能感兴趣的:(编程基础-C/C++,c++,c语言,算法)