当前位置: 首页 > news >正文

C++初阶--模板

目录

非类型模板参数

模板的特化

        什么是特化

        函数模板特化

        类模板特化

                全特化

                偏特化

模板分离编译

        什么是分离编译

        为什么模板不支持分离编译

        解决方法

模板的优点和缺陷


非类型模板参数

类型形参:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。
非类型形参:用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。
//非类型模板参数--整形常量
template<class T, size_t N = 10>
class MyStack
{
public:
	void Push(const T& x)
	{}
private:
	T _a[N];
	size_t _top;
};

int main()
{
	MyStack<int, 100> st1;
	MyStack<int, 200> st2;

	return 0;
}
  1. 非类型模板参数只能是整形。
 2. 非类型模板参数必须在编译时就能确认结果。   

模板的特化

什么是特化:

在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。
函数模板--参数匹配
//函数模板--参数匹配
template<class T>
bool ObjLess(T left, T right)
{
	return left < right;
}

bool ObjLess(Date* left, Date* right)
{
	return *left < *right;
}

template<>
bool ObjLess<Date*>(Date* left, Date* right)
{
	return *left < *right;
}

int main()
{
	cout << ObjLess(1, 2) << endl;
	Date* p1 = new Date(2011, 1, 23);
	Date* p2 = new Date(2013, 3, 23);

	//参数匹配
	cout << ObjLess(p1, p2) << endl;

	return 0;
}

函数模板特化

步骤:

1. 必须要先有一个基础的函数模板
2. 关键字template后面接一对空的尖括号<>
3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型
4. 函数形参表: 必须要和模板函数的基础参数类型完全相同
template<class T1,class T2>
class Data
{
public:
	Data()
	{ 
		cout << "Date<T1, T2>" << endl;
	}
private:
	T1 _d1;
	T2 _d2;
};

//特化--特殊化
template<>
class Data<int, char>
{
public:
	Data() 
	{ 
		cout << "Data<int, char>" << endl; 
	}
private:
	int _d1;
	char _d2;
};

int main()
{
	//Data<int, int> d1;
	//Data<int, char> d2;

	qwe::priority_queue<Date*> pq;

	pq.push(new Date(2022, 3, 26));
	pq.push(new Date(2021, 10, 26));
	pq.push(new Date(2023, 3, 26));

	while (!pq.empty())
	{
		cout << *pq.top();
		pq.pop();
	}
	cout << endl;

	return 0;
}

类模板特化

全特化

将模板参数列表中所有的参数都确定化
template<class T1, class T2>
class Data
{
public:
	Data()
	{
		cout << "Data<T1, T2>" << endl;
	}
private:
	T1 _d1;
	T2 _d2;
};

//全特化
template<>
class Data<int, char>
{
public:
	Data()
	{
		cout << "Data<int, char>" << endl;
	}
};

偏特化

任何针对模版参数进一步进行条件限制设计的特化版本
//偏特化
template<class T1>
class Data<T1, char>
{
public:
	Data()
	{
		cout << "Data<T1, char>" << endl;
	}
};

template<class T1, class T2>
class Data<T1*, T2*>
{
public:
	Data()
	{
		cout << "Data<T1*, T2*>" << endl;
	}
};

template<class T1, class T2>
class Data<T1&, T2&>
{
public:
	Data()
	{
		cout << "Data<T1&, T2&>" << endl;
	}
};

对非类型模板参数也可以

template<size_t N>
class A
{
public:
	A()
	{
		cout << "A<N>" << endl;
	}
};

template<>
class A<10>
{
public:
	A()
	{
		cout << "A<10>" << endl;
	}
};

模板分离编译

什么是分离编译

        一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。

为什么模板不支持分离编译

        模板函数的代码不能直接编译成二进制代码,其中要有一个“实例化”的过程。解决方案在分离式编译的环境下,编译器编译某一个.cpp文件时并不知道另一个.cpp文件的存在,也不会去查找。这种模式在没有模板的情况下可以运行,但因为模板仅在需要的时候才会实例化出来,所以,当编译器只看到模板的声明时,它不能实例化该模板,只能创建一个具有外部连接的符号并期待连接器能够将符号的地址决议出来。但是当实现该模板的.cpp文件中没有用到模板的实例时,编译器就没有去实例化,所以,整个工程的.obj中就找不到一行模板实例的二进制代码,于是连接器也黔驴技了。

解决方法

1.显示实例化

2.声明和定义不分离

模板的优点和缺陷

优点:
1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生
2. 增强了代码的灵活性
缺陷:
1. 模板会导致代码膨胀问题,也会导致编译时间变长(实例化过程消耗)
2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误

相关文章:

  • [Android]Bitmap Drawable
  • 【docker概念和实践 3】 注册阿里云账号、应用阿里云数据源
  • 手把手教你学51单片机-点亮你的LED
  • 华为数字化转型之道 平台篇 第十三章 变革治理体系
  • 23种设计模式(十)——原型模式【对象创建】
  • 数据挖掘之超参调优技巧
  • hids wazuh 系列3-内网扫描规则
  • (003) 简述UDP与TCP的区别
  • Open3D 区域生长分割(python详细过程版)
  • Jetson硬件平台状态查看工具jtop安装,服务器平台上可以通过nvtop工具来查看资源使用情况
  • 华为数字化转型之道 平台篇 第十一章 统一的数据底座
  • Gradle vs Maven 基本对比(一)
  • PowerSNMP for .NET 6.1.0.0 Crack
  • 回顾在江西博微科技工作9个月回顾(吐槽)
  • java的数据类型:引用数据类型(String、数组、枚举)
  • [标准库]STM32F103R8T6 串口的收发
  • mysql是如何插入一条数据的
  • C语言基础 — ( 函数——模块化设计)
  • 设计模式_行为型模式 -《责任链模式》
  • 大模型算法演进