|
#pragma once

#include <iostream>

 /**//*/////////////////////////////////////////////
C++ 模板

/////////////////////////////////////////////*/


 /**//*
--- 函數模板 ---
*/

 /**//// 聲明 template <typename T1, typename T2>
void TFunc(T1, T2);

 /**//// 一般定義 template <typename T1, typename T2>
void TFunc(T1, T2)
  {
std::cout << "一般" << std::endl;
}

 /**//// 偏特化,T2(int) template <typename T1>
void TFunc(T1, int)
  {
std::cout << "偏特化" << std::endl;
}

 /**//// 全特化,T1(char), T2(char) template <>
void TFunc(char, char)
  {
std::cout << "全特化" << std::endl;
}

 /**//// 重載,函數的參數個數不同 template <typename T1>
void TFunc(T1)
  {
std::cout << "重載" << std::endl;
}

 /**//// 函數模板不允許默認的參數類型,而類模板允許 // template <typename T1, typename T2=int>
// void DefaultParamFun(T1, T2){}

 /**//// 測試模板函數 void Test_Func()
  {
TFunc<int,int>(0, 0); // 一般
TFunc<char>('a', 0); // 偏特化
TFunc('a','a'); // 全特化
TFunc<int>(0); // 重載

std::cout << std::endl;
}


 /**//*
--- 類模板 ---
*/

 /**//// 類模板允許默認的參數類型 template <typename T1, typename T2=int>
class TClass
  {
public:
TClass()
 {
std::cout << "類模板,一般" << std::endl;
}

template <typename P>
void Test(P)
 {
std::cout << "類模板,模板成員函數,一般" << std::endl;
}

 /**//// 特化成員函數 p(int)
template <>
void Test(int)
 {
std::cout << "類模板,模板成員函數,偏特化" << std::endl;
}

static int m_nData;
};

 /**//// 模板類靜態成員初始化 template<>
int TClass<int,int>::m_nData = 0;

 /**//// 類模板偏特化 T2(int) template <typename T1>
class TClass<T1, int>
  {
public:
TClass()
 {
std::cout << "類模板,偏特化" << std::endl;
}
};

 /**//// 類的成員函數模板 class TMemFun
  {
public:
template <typename T>
void Test(T)
 {
std::cout << "類的成員函數模板" << std::endl;
}
};

 /**//// 測試模板類 void Test_Class()
  {
TClass<bool,char> tClass1;
tClass1.Test('a'); // 模板成員函數,一般
tClass1.Test(0); // 模板成員函數,偏特化

TClass<bool,int> tClass2; // 類偏特化

TMemFun tMemFun;
tMemFun.Test(1); // 類的成員函數模板

std::cout << std::endl;
}


 /**//*
--- 類型自動轉換 ---
1、數組與指針互轉
2、限制修飾符const與非const互轉
*/

 /**//// 參數為指針 template <typename T>
 void PtrFun(T*) {}

 /**//// 參數為數組 template <typename T>
 void ArrayFun(T[]) {}

 /**//// const參數 template <typename T>
 void ConstFun(const T) {}

 /**//// 非const參數 template <typename T>
 void UnConstFun(T) {}

 class CBase {}; // 父類
 class CDerived : public CBase {}; // 子類

template <typename T>
 void ClassFun(T) {}

void Test_TypeConversion()
  {
int nValue = 1;
ConstFun(nValue); // 非const --> const

const int cnValue = 1;
UnConstFun(cnValue); // const --> 非const

 int nArray[2] = {0,0};
PtrFun(nArray); // 數組 --> 指針

int* pInt = NULL;
ArrayFun(pInt); // 指針 --> 數組

CDerived derived;
ClassFun<CBase>(derived); // 子類 --> 父類

// CBase base;
// ClassFun<CDerived>(base); // 不允許,父類 --> 子類
}

void Test_Template()
  {
Test_Func();
Test_Class();
Test_TypeConversion();
}

|