【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;
}

 

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