c++模板学习笔记——定义模板(2)

  • 在程序中,我们最常见到的是作用域这个概念,那么模板的作用域是什么?
    模板遵循普通的作用域规则,一个模板参数名的可用范围是在其声明之后,至模板声明或定义结束之前。同样,模参数会隐藏外层作用域中声明的相同名字。(模板参数名不可重用)
  • 模板如何使用类的类型成员
    对于非模板类来说,由于编译掌握类的定义,因此通过域运算符(::)我们可以知道通过域运算符访问的名字是类型还是static成员;
    对于类模板来说,只有类模板实例化之后,编译器才会掌握类的定义,因此为了处理模板,编译器必须知道名字是否表示一个类型。
std::string::size_type a; //由于编译器有string的定义,因此知道size_type是一个类型
T::size_type * p ;   //此时编译器不知道size_type是一个类型或是一个static值
typename T::size_type *q;  //显式告诉编译器该名字是一个类型

注意:当我们希望通知编译器一个名字表示类型是,必须使用关键字typename,而不能使用class。

  • 默认模板实参
    在新标准中,我们可以为函数和类模板提供默认实参。
//compare 有一个默认模板实参less<T> 和一个默认函数实参F()
template<typename T,typename F = less<T>>
int compare(const T& v1,const T& v2,F f = F()){
	if(f(v1,v2)) return -1;
	if(f(v2,v1)) return 1;
	return 0;
}

类模板默认实参

template<class T = int> class Numbers{
public:
	Numbers(T v = 0):val(v){}
private:
	T val;	
};
Numbers<long double> lots_os_precision;
Numbers<> average_precision;    //空<>表示我们希望使用默认类型
  • 成员模板
    一个类(无论是普通类还是类模板)可以包含本身是模板的成员函数,这种成员被称为成员模板 (成员模板不能是虚函数)
  1. 普通类的成员模板:在调用时编译器推断实参类型;
  2. 类模板的成员函数:类和成员各自有自己的独立的模板参数
    例如:我们将为Blob(vector访问检查类)类定义一个构造函数,他接受两个迭代器,表示要拷贝的元素范围,由于我们希望支持不同类型序列的迭代器,因此将构造函数定义为模板;
template<typename T> class Blob{
	template<typename It> Blob(It b,It e);
};

//在类外定义时,必须同时为类模板和成员模板提供模板参数列表
template<typename T>
template<typename It>
Blob<T>::Blob(It b,it e):data(std::make_shared<std::vector<T>>(b,e)){}
  • 控制实例化
    由于模板只有在使用时才会进行实例化,因此相同的实例可能出现在多个对象文件中。
    在新标准中,我们可以通过显式实例化类避免这种开销。形如下列
extern template function/class;   //实例化声明
template function/class;         //实例化定义

当编译器遇见一个实例化声明时,说明在其他文件中已经存在了该实例,不必在本文件中再次实例化;当遇到一个实例化定义时,编译器将在本文件对其进行实例化;
对于每个实例化声明,在程序中某个位置必须有器显式的实例化定义
实例化定义会实例化所有成员(包括内联的成员函数):当编译器遇到一个实例化定义时,它不了解程序使用那些成员函数,因此,编译器会实例化该类的所有成员 (我们用来实例化一个类模板的类型,必须能用于模板的所有成员)


参考文献: C++ Primer(第五版)
个人学习笔记,仅作学习记录用途

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值