在看阿鲤的这篇文章之前请先看一下模板的简单介绍
以下是阿鲤对模板的扩展,希望能帮到部分同学,若有误请慷慨指出。
1:非类型模板参数
2:模板的特化
3:类型萃取
4:模板的分离编译
5:常见面试题
一:非类型模板参数
非类型模板参数是指用一个常量作为类(函数)模板的参数,在类(函数)模板中可将该参数当成常量来使用。
eg:
#include<iostream>
using namespace std;
template <class T , size_t N = 10>//非类型模板参数
class Test
{
int m_array[N];
public:
Test()
{
cout << N << endl;
}
};
int main()
{
const int i = 100;
Test<int> t1;
Test<int, i> t2;
Test<int, 1000>t3;
system("pause");
return 0;
}
注意:
1:非类型模板参数通常是作为静态顺序表的模板。
2:浮点数,类对象,字符串是不允许作为非类型模板参数的。
3:非类型模板参数必须在编译期间确认结果
二:模板的特化
1:概念:
通常情况下使用模板可以实现一些与类型无关的代码,但对于一些特殊的可能会得到一些错误的结果:就好比下面这段代码
#include <iostream>
using namespace std;
template<typename T>
T Max(T t1, T t2)
{
return (t1 > t2) ? t1 : t2;
}
int main() {
int i = Max(10, 5);
const char* p = Max<const char*>("very", "good");
cout << "i:" << i << endl;
cout << "p:" << p << endl;
system("pause");
return 0;
}
在没有特化的模板函数内部用>对字符串进行比较是错误的,所以我们就需要模板的特化来解决这个问题。
2:函数模板特化
模板特化的步骤:
1:必须有一个基础的模板函数
2:关键字template后面接一对空的<>
3:函数名后跟一对<>,<>中指定需要的特化类型
4:函数形参表:必须要和模板函数的基础参数类型完全相同。
eg:
#include <iostream>
using namespace std;
template<typename T>
T Max(T t1, T t2)
{
return (t1 > t2) ? t1 : t2;
}
typedef const char* CCP;
template<>
CCP Max<CCP>(CCP s1, CCP s2)
{
return (strcmp(s1, s2) > 0) ? s1 : s2;
}
int main() {
int i = Max(10, 5);
const char* p = Max<const char*>("very", "good");
cout << "i:" << i << endl;
cout << "p:" << p << endl;
system("pause");
return 0;
}
3:类模板特化
3.1:全特化:将模板参数类中所有的参数都去确定
eg:
#include<iostream>
using namespace std;
template<class T1, class T2>
class Data
{
public:
Data()
{
cout << "Data<T1, T2>" << endl;
}
T1 m_a;
T2 m_b;
};
template<>
class Data<int, char>
{
Data()
{
cout << "Data<T1, T2>" << endl;
}
int m_a;
char m_b;
};
int main()
{
system("pause");
return 0;
}
3.2:偏特化:任何针对模板参数进一步进行条件设计的特化版本。
3.2.1:部分特化:将模板参数列表中的一部分参数特化
using namespace std;
template<class T1, class T2>
class Data
{
public:
Data()
{
cout << "Data<T1, T2>" << endl;
}
T1 m_a;
T2 m_b;
};
template<class T1>
class Data<T1,int>
{
Data()
{
cout << "Data<T1, T2>" << endl;
}
T1 m_a;
int m_b;
};
int main()
{
system("pause");
return 0;
}
3.2.2:参数更进一步的限制
#include<iostream>
using namespace std;
template<class T1, class T2>
class Data//基础版本
{
public:
Data()
{
cout << "Data<T1, T2>" << endl;
}
T1 m_a;
T2 m_b;
};
template<class T1>
class Data<T1,int>//部分特化
{
public:
Data()
{
cout << "Data<T1, int>" << endl;
}
T1 m_a;
int m_b;
};
template<class T1, class T2>
class Data<T1*, T2*>//指针版本特化
{
public:
Data()
{
cout << "Data<T1*, T2*>" << endl;
}
T1 m_a;
T2 m_b;
};
template<class T1, class T2>
class Data<T1&, T2&>//引用版本特化
{
public:
Data(const T1 &a, const T2 &b) :
m_a(a),
m_b(b)
{
cout << "Data<T1&, T2&>" << endl;
}
T1 m_a;
T2 m_b;
};
int main()
{
Data<double, char>d1;
Data<double, int>d2;
Data<double*, int*>d3;
Data<int&, char&>d4(5,6);
system("pause");
return 0;
}
三:类型萃取
四:模板的分离编译
五:常见面试题