【C++】模板进阶

  越是简单而美好的东西,在落向现实的时候,越会变得面目全非。

前言 

  这是我自己学习C++的第十篇博客总结。后期我会继续把C++学习笔记开源至博客上。

  上一期笔记是关于C++的stack类与queue类知识,没看的同学可以过去看看:

【C++】STL容器---Stack类与Queue类-CSDN博客https://blog.csdn.net/hsy1603914691/article/details/145817990

非类型模板参数 

1. 模板参数分为类型模板参数非类型模板参数

2. 非类型模板参数,就是用一个整形常量作为模板的一个参数在模板中可将该参数当成整形常量来使用

#define _CRT_SECURE_NO_WARNINGS
#include 
using namespace std;
template
class Stack
{
private:
	T _arr[N];
	int _top;
};
int main()
{
	Stack s1;//N不传值默认为20
	Stack s2;
	return 0;
}

模板的特化

1. 函数模板不建议使用特化,通常都是将该函数直接给出。

2. 类模板的特化分为全特化偏特化

3. 全特化即是将模板参数列表中所有的参数都确定化

4. 偏特化有以下两种表现方式:将模板参数类表中的一部分参数进行特化针对模板参数类型进行限制

#define _crt_secure_no_warnings
#include 
using namespace std;

//普通类模板
template
class Data
{
public:
	Data() { cout << "Data" << endl; }
private:
	T1 _d1;
	T2 _d2;
};

//全特化类模板
template<>
class Data
{
public:
	Data() { cout << "Data" << endl; }
private:
	int _d1;
	char _d2;
};

//偏特化类模板
template
class Data 
{
public:
	Data() { cout << "Data" << endl; }
private:
	T1 _d1;
	int _d2;
};

//两个参数偏特化为指针类型
template 
class Data 
{
public:
	Data() { cout << "Data" << endl; }
private:
	T1* _d1;
	T2* _d2;
};

//两个参数偏特化为引用类型
template 
class Data 
{
public:
	Data(const T1& d1, const T2& d2)
		: _d1(d1)
		, _d2(d2)
	{
		cout << "Data" << endl;
	}
private:
	const T1& _d1;
	const T2& _d2;
};

模板分离编译 

  1. 编译阶段

    • a.cpp中,编译器看到了Add模板函数的定义
    • main.cpp中,编译器看到了Add模板函数的调用
    • 由于模板函数的实例化是在使用时进行的,因此在a.cpp中并没有为Add和Add实例化具体的函数
  2. 链接阶段

    • main.obj中,编译器知道需要调用AddAdd
    • 但是,在a.obj中,并没有为这些类型实例化的具体函数。
    • 因此,链接器找不到这些函数的地址,导致链接错误。

【C++】模板进阶_第1张图片

解决措施:将模板函数的定义放在头文件中,这样每次包含头文件时都会实例化模板。

模板优缺点 

模板优点 

1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库因此而产生。
2. 增强了代码的灵活性。

模板缺点 

1. 模板会导致代码膨胀问题,也会导致编译时间变长。
2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误。

致谢 

  感谢您花时间阅读这篇文章!如果您对本文有任何疑问、建议或是想要分享您的看法,请不要犹豫,在评论区留下您的宝贵意见。每一次互动都是我前进的动力,您的支持是我最大的鼓励。期待与您的交流,让我们共同成长,探索技术世界的无限可能!

你可能感兴趣的:(C++,c++)