c++的模板进阶

前言:
模板也能传入非类型,可用来代替宏;

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>

using namespace std;
template<size_t N = 10,class T = int>
class test
{
public:
	test(const T& a)
	{
		cout << N << "   " << a << endl;
	}
private:
	T arr[N];


};
int main()
{

	test<100, char> a('d');

}

一、函数模板

1.1如自定义类型建立的模板一样函数也可以有模板

比自定义类型的模板不一样的是自定义class test类在实例化时即使test的模板做了全缺省模板也必须要在test后跟<>才可以编译;

template<class T>
T add(T a, T b)
{
	return a > b;
}
int main()
{

	//test<100, char> a('d');
	cout << add(10, 1) << endl;;
	cout << add<double>(10.1, 1.2) << endl;;


}

1.2函数模板的特化

和函数重载有些相似,在实例化调用函数时函数会找到最匹配自己的特化

template<class T>
void add(const T& a,const T& b)
{
	cout << "this is T" <<endl;
}
template<>
void add<char>(const char& a, const char& b)
{

	cout << "this is char" <<endl;

}//函数特化
template<class T>

int main()
{

	//test<100, char> a('d');
	add(10, 10);
	add('a', 'b');
	

}

输出结果

可知如果有去全特化的函数会有先走全特化函数:add(‘a’,‘b’);没有匹配的特化才会走原本的模板函数进行实例化;

注意函数没有偏特化;

值得注意的是函数对指针进行特化时:

template<class T>
void add(const T& a,const T& b)
{
	cout << "this is T" <<endl;
}
template<>
void add<char*>( char*const & a,  char*const& b)
{

	cout << "this is char" <<endl;

}//函数特化(对指针)

写成char*const & a而不是const char* & a的原因是在标准化下的const修饰的是a这个变量是他本身不可以改变,只有char*const &a,const修饰的才是a本身, const char* & a修饰的是*a也就是指针的指向数据,与const T& a不同所以会发生找不到标准化模板;

二、自定义类型模板

自定义模板新增了偏特化即:只特化参数的一部分

template<class T1, class T2>

class Data

{

public:

	Data() { cout << "Data<T1, T2>" << endl; }

private:

	T1 _d1;

	T2 _d2;

};

template <class T1>

class Data<T1, int>

{

public:

	Data() { cout << "Data<T1, int>" << endl; }

private:

	T1 _d1;

	int _d2;

};//自定义模板类的偏特化

template <typename T1, typename T2>

class Data <T1*, T2*>

{

public:

	Data() { cout << "Data<T1*, T2*>" << endl; }

private:

	T1 _d1;

	T2 _d2;

};

template <typename T1, typename T2>

class Data <T1&, T2&>

{

public:

	Data(const T1& d1, const T2& d2)

		: _d1(d1)

		, _d2(d2)

	{

		cout << "Data<T1&, T2&>" << endl;

	}

private:

	const T1& _d1;

	const T2& _d2;

};

int main()

{

	Data<double, int> d1;

	Data<int, double> d2;

	Data<int*, int*> d3;

	Data<int&, int&> d4(1, 2);

	return 0;

}

Data<double, int> d1; // 调用特化的int版本

Data<int, double> d2; // 调用基础的模板

Data<int *, int*> d3; // 调用特化的指针版本

Data<int&, int&> d4(1, 2); //调用特化的引用版本

强调一下

模板函数模板自定义类型不能声明和定义分离(会很麻烦)非要分离必须在定义处显式实例化对象:template

 void func(const int a);且是在主页中用一次func的不同模板生成的func你就要实例化一次,不然在程序链接的情况下会链接不通过程序找不到地址;

// math_utils.hpp
#pragma once
template<typename T>
T add(T a, T b);  // 仅声明

// math_utils.cpp
#include "math_utils.hpp"

// 定义
template<typename T>
T add(T a, T b) {
    return a + b;
}

// 显式实例化
template int add<int>(int, int);       // 显式实例化 int 版本
template double add<double>(double, double);  // 显式实例化 double 版本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值