【C++】模板 全特化、偏特化

    在定义模板类型参数时,typename和class作用相同! 

1. 函数模板  

    在编译阶段执行   a  定义点   模板头部          b  调用点   模板函数

2. 模板函数

3. 模板的实例化  // 函数模板到模板函数的一个转换过程

4.模板的实例推演

int main()
{
	Sum(10,20);  //模板的实参推演
	//程序可以运行,系统会自动判断10和20的数据类型,进行推演

	return 0;
}

template <typename T,typename E>
T Sum <T a,E b>;
//当Sum内实参数据类型不同时

注意事项:  a 不能产生二义性; b  有实参才能推演

5. 模板的特例化(专用化):模板类型不能满足特殊类型的需求

#include<iostream>

template <typename T>

bool Compare(T a,T b)
{
	return a>b; 	//代码错误,只比较地址,不比较地址内值
}
/*
bool Compare<char *>("Hello","World")
{
    return a>b;
}
*/

int main()
{
	Compare<char *>("Hello","World");
	
	return 0;
}
#include<iostream>

template<typename T>
bool Compare(T a, T b)
{
	std::cout << "template<typename T> bool Compare(T,T)" << std::endl;
	return a > b;
}

template <> //特例化[已经全特化,为空]
bool Compare<char *>(char *a,char *b)
{
	return strcmp(a,b)>0;
}

int main()
{
	Compare<char *>("Hello","World");
	
	return 0;
}

    特例化应该符合模板的实例化逻辑:

    a 完全特例化[函数模板]  全特化  [具体到某一个类型]

    b 部分特例化[类模板]  偏特化  [具体到一部分类型]

    特例化的调用优先级 > 模板实例化            [所以特例化直接调用]

6. 模板的类型参数

7. 模板的非类型参数

     特点: a 模板的非类型参数是常量

                 b 模板的非类型参数不能是float、double类型

template<typename T, int LEN>
//int LEN 就是非类型参数

8. 模板的默认值

#include <iostream>

template<typename A = int, typename B, typename C = double>
C Add(A a, B b)
{
	//C c = C();  //初始化
	std::cout << "A : " << typeid(A).name() << std::endl;  //double
	std::cout << "B : " << typeid(B).name() << std::endl;  //int
	std::cout << "C : " << typeid(C).name() << std::endl;  //double
	return a + b;
}

int main()
{
	auto rt = Add(10.1, 20);
	std::cout << "rt : " << typeid(rt).name() << std::endl;
	return 0;
}

     函数模板的默认值,不是C++98标准,是C++11  【如果有实参推演,则不使用默认值,反之则使用】

     类模板的默认值,是C++98标准  【不遵循自右向左依次赋予的规则】

9. 模板接收不明确类型的返回值

     auto 自适应的调节类型

auto rt = Add(10.1, 20);

10. 模板的重载

      a  普通函数版本 

      b  模板版本

      c   模板特例化版本

      优先级:1 > 3 > 2       ps : 要求精确匹配!

 11. 模板的显式实例化

//test.cpp
template<typename T>
T Sum(T a, T b)
{
	return a + b;
}
//int a = Sum<int>(10, 20);
template int Sum<int>(int, int);

//main.cpp
template<typename T>
T Sum(T, T);

int main()
{
	Sum<int>(10, 10);
	Sum<double>(10.2, 10.1);
	return 0;
}
template int Sum<int>(int,int)  //显示实例化

         模板一般在.h文件中实现

【用模板完成冒泡排序!】

#include <iostream>


template<typename T, int LEN>
void Sort1(T arr[])
{
	//LEN = 10;
	T tmp = T();
	for (int i = 0; i < LEN - 1; i++)
	{
		for (int j = 0; j < LEN - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
template<typename T>
void Sort(T arr[], int len)
{
	T tmp = T();
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
template<typename T>
void Show(T arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		std::cout << arr[i] << " ";
	}
	std::cout << std::endl;
}
int main()
{
	int arr[] = { 21, 32, 43, 234, 23, 42, 4212, 3 };
	int len = sizeof(arr) / sizeof(arr[0]);
	Show(arr, len);
	Sort(arr, len);
	Show(arr, len);

	//Sort1<int, sizeof(arr) / sizeof(arr[0])>(arr);
	Sort1<int, len>(arr);

	const int a = 10;
	int b = 20;
	const int c = b;
	c = 10;
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章