c++模板 进阶(1:非类型模板参数 2:模板的特化)

在看阿鲤的这篇文章之前请先看一下模板的简单介绍

以下是阿鲤对模板的扩展,希望能帮到部分同学,若有误请慷慨指出。

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

 

三:类型萃取 

 

四:模板的分离编译

 

五:常见面试题

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值