C++模板中的名称

名称的分类:
标识符、运算符id、类型转换函数id、模板id、非受限id、受限id、受限名称、非受限名称、依赖性名称、非依赖性名称
如果一个名称使用域解析运算符或者成员访问运算符来显式表明它所属的作用域,就称该名称为受限名称。
如果一个名称依赖于模板参数,就称为依赖性名称。

名称查找:
受限名称的名称查找是在一个受限作用域内部进行的,该受限作用域由一个限定的构造所决定,如果该作用域是一个类,那么查找范围可以到达它的基类;但不会考虑它的外围作用域。
非受限名称的查找则相反,可以在所有外围类中逐层地进行查找(但在某个类内部定义的成员函数定义中,它会先查找该类和基类的作用域,然后才查找外围类的作用域)

ADL(argument-dependent lookup)依赖于参数的查找:
ADL只能应用于非受限名称。
唯一例外情况是:忽略using指示符

 

友元名称插入:

C++标准规定:
通常,友元声明在外围(类)作用于中是不可见的。
如果友元函数所在的类属于ADL的关联类集合,那么在这个外围类是可以找到该友元声明的。
对于涉及在关联类中友元查找的调用,会导致该关联类被实例化,如f(*p)。

解析模板:
依赖性类型名称:

依赖型受限名称并不会代表一个类型,除非在该名称的前面有关键字typename前缀。
当类型名称具有以下性质时,就应该在该名称前面添加typename前缀:
1.名称出现在一个模板中
2.名称是受限的
3.名称不是用于指定基类继承的列表中,也不是位于引入构造函数的成员初始化列表中
4.名称依赖于模板参数
只有当前面3个条件同时满足的情况下,才能使用typename前缀。

 

依赖性模板名称

和依赖性类型名称一样,要让编译器知道所引用的依赖型名称是一个模板,需要在该名称前加template关键字,否则编译器不把它作为一个模板名称。

这个例子给出了何时需要在运算符(::,->和.,用于限定一个名称)的后面加上template,更精确的说法是:如果限定符号前面的名称的类型依赖于某个模板参数,并且紧接着在限定符后面的是一个template-id(也就是指一个后面带有尖括号内部实参列表的模板名称)那么就应该使用关键字template,例如下面的表达式中:

p.template Deep<N>::t();

p的类型依赖于模板参数T。然而C++编译器并不会查找Deep来判断是否是一个模板,因此我们必须显示指定Deep是一个模板名称。

 

派生和类模板:

非依赖型基类:无需知道模板实参就可以确定类型的基类。就是说,基类名称是用非依赖性名称表示的。例如:

模板中的非依赖性基类和普通非模板类中的基类的性质很相似,但有一点区别:对于模板中非依赖性基类而言,如果在派生类里查找一个非受限名称,那就会先查找这个非依赖性基类,然后在查找模板参数列表,如上述例子。

 

依赖性基类:

对于模板中的非依赖型名称,将会在看到的第一时间进行查找,但不会在依赖型基类中进行查找。
在允许使用this->前缀的地方都使用this->前缀。
如果不断重复的限定会让代码不雅观,可以在派生类中只引入依赖型基类中的名称一次:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值