C++模板

函数模板

函数模板的基本用法

template<typename T>
bool compare(T a, T b)
{
	return a > b;
}
int main()
{
	compare<int>(10, 20);
	compare<double>(10.2, 20.3);
	return 0;
}
  • 传入的参数类型是在什么时候替换进去的,如何替换的?
  • 模板是不可以直接运行的
  • 函数模板会在编译期根据使用情况生成对应的函数
  • 模板不编译,但是模板生成的函数指令会编译
  • 模板中的语法错误,会在生成对应的指令时候被编译出错误
  • 函数模板有类型自推的能力,使用函数模板可以不用传模板类型参数
  • 函数模板特例化的优先级比普通函数要高
  • 普通函数的优先级比模板特例化要高
template<typename T>
void BubbleSort(T* arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		bool tag = true;
		for (int j = 0; j < len - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				tag = false;
				T tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		if (tag == true)
		{
			return;
		}
	}
}
template<typename Y>
void Show(Y* arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
	cout << typeid(Y).name() << endl;//查看模板参数类型
}
int main()
{
	int arr[] = { 43,23,67,98,67,37,90,12,27,73 };
	int len = sizeof(arr) / sizeof(arr[0]);
	BubbleSort(arr, len);
	Show(arr, len);
	return 0;
}
//普通函数>特例化模板>函数模板
template<typename A>
bool compare(A a, A b)
{
	return a > b;
}
template<>//特例化模板
bool compare(const char* a, const char* b)
{
	cout << "bool compare(const char* a,const char* b)" << endl;
	return strcmp(a, b) > 0;
}
bool compare(const char* a, const char* b)//普通函数
{
	cout << "bool compare(const char* a,const char* b)" << endl;
	return strcmp(a, b) > 0;
}
int main()
{
	compare(12, 13);
	compare("aaa", "bbb");//如果没有函数模板的特例化会调用template<typename A>,结果会有问题,所以用函数模板的特例化来解决这一问题
	return 0;
}

类模板

  • 类模板不编译
  • 会在编译期根据使用方式,生成对应的类代码(指令)
  • 类模板中没有使用到的成员方法不会再编译期生成对应的指令
  • 类模板使用时候必须加上模板类型参数,类模板无法自己推导参数类型
  • 类模板也有特例化
  • 类模板的成员方法在类外实现与正常方式不同
  • 类模板的成员方法只能在头文件中实现/或者在使用到的cpp文件中实现
//类模板
template<typename T>
class Arr
{
public:
	Arr();
	~Arr();
	Arr(const Arr& src);
	Arr& operator=(const Arr& src);

	void push_back(const T& val);
	void pop_back();
	T& back();
	T& operator[](int pos);
	int size();
    //没有使用到的成员方法不会再编译期生成对应的指令
    template<typename T> 
    friend ostream& operator<<(ostream& out, Arr<T>& src);
private:
	T* _arr;
	int len;
	int _val_len;
};
template<typename T> //不是成员方法的类外实现,与类没有关系,只是在类中绑定了友元
ostream& operator<<(ostream& out, Arr<T>& src)
{
	for (int i = 0; i < src.size(); i++)
	{
		out << src[i] << endl;
	}
	cout << endl;
} 
int main()
{
	Arr<int>A;//类模板使用时候必须加上模板类型参数,类模板无法自己推导参数类型
    A.pop_back();//预编译时不会报错,编译之后会出错,找不到函数的实现
	return 0;
}
void Arr::push_back(const T& val);//错误,模板不是类,加上类型参数才变成类
//类模板中的函数成员在类外的实现方法
template<typename T> //加上类型参数后,就要写模板
void Arr<T>::push_back(const T& val)//正确
{
	cout << "void Arr<T>::push_back(const T& val)" << endl;
}

 

//arr.h
template<typename T>
class Arr
{
public:
	Arr()
    {
        cout<< "Arr()" <<endl;
    }
	~Arr()
    {
        cout<< "~Arr()" <<endl;
    }
	Arr(const Arr& src);
	Arr& operator=(const Arr& src);

	void push_back(const T& val);
	void pop_back();
	T& back();
	T& operator[](int pos);
	int size();
private:
	T* _arr;
	int len;
	int _val_len;
};
template<typename T>
void Arr<T>::push_back(const T& val)
{
	cout << "void Arr<T>::push_back(const T& val)" << endl;
}

//arr.cpp
template<typename T>
void Arr<T>::pop_back()
{
	cout << "void Arr<T>::pop_back()" << endl;
}

//main.cpp
//类模板的成员方法只能在头文件中实现/或者在使用到的cpp文件中实现
int main()
{
	Arr<int>A;
	A.push_back(10);//没有问题
	A.pop_back();//出错
	return 0;
}
//为什么类模板的成员方法不能在其他cpp文件中实现?
//类模板需要在编译时期将使用到的成员方法生成对应的指令
//编译期时只针对单文件的
//如果将类模板的成员方法实现在了其他文件,编译期使用到该方法的文件不可见,就无法生成对应的指令

 

函数模板与类模板的区别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值