1.受限名称和依赖型名称:如果一个名称使用: :或  .  ->来显示作用域,则为受限名称。如果一个名称依赖于模板参数,我们称它为依赖型名称。

一:名称查找

受限名称和非受限名称的查找:

int x;class B {
public:int i;
};class D : public B {};void f(D* pd)
{pd->i = 3;//会找 b中的xD::x = 2;//error 不会去外围作用域查找x
}

注:受限名称的名称查找在一个受限的作用域内部进行,如果该作用域是一个类,那么查找范围可以达到它的基类。但不会考虑外围作用域。

extern int count;//(1)int lookup_example(int count)//(2)
{if (count < 0) {int count = 1;//(3)lookup_example(count);//非受限 引用3}return count + ::count;//1.非受限 引用2   2.受限 引用1
}

注:非受限类型的普通查找方式。

add:非受限名称的另一种查找方式,依赖于参数查找(argument-dependent lookup,  ADL)

参考:https://www.cnblogs.com/GnibChen/p/8599981.html

二:友元名称插入

考虑:

template <typename T>
class C
{friend void f();friend void f(C<T> const&);
};void g(C<int>* p)
{f();//f()在此可见吗f(*p);//这个呢?
}

其中包含友元函数的类位于作用域A。

三:插入式类名称

在类本身作用域中插入该类的名称,我们称该名称为插入式类名称。可访问。

四,解析模板

一些例子:

1.x<1>(0) 如果词法分析发现x是模板名称则 0 被强转为 x(1)类型 否则分析为 (x < 1) > 0

2.

template<bool B>
class Invert {
public:static bool const result = !B;
};void g()
{bool test = Invert<(1 > 0)>::result;//圆括号不能省略
}

3.之前说过的 List<List<int> >   a;

c++ maximum munch扫描原则,让一个标记具有尽可能多的字符,所以>>会被看作右移

还有

class X{

};

List<::X> many_X;//error

因为 <:会被看作符号【    则为List [:X> many_X;

4.依赖型类型名称

例如:

template <typename T>
class Trap {
public:enum { x };
};template <typename T>
class Victim {
public:int y;int answer;void poof(){//answer = Trap<T>::x*y;}
};template <>
class Trap<void>
{
public:typedef int x;
};void boom(Victim<void>& bomb)
{bomb.poof();
}

注: 没有Trap<void> 特化之前 Trap<T>::X被理解为一个值, 特化之后为一个类型。

typename:当类型名称具有以下性质时,应该在名称前添加typename

1)名称出现在一个模板中

2)名称是受限的

3)名称不是用于指定基类继承的列表中,也不是位于引入构造函数的成员初始化列表中

4)名称依赖于模板参数

前面三个条件同时满足 用typename前缀。

(待理解)

5.依赖型模板名称

在限定运算符后面使用关键词template .

如果限定符号前面的内容的类型要依赖于模板参数并且紧跟限定符号后面的是template-id,那么就应该使用关键词typename

例如 p.template Deep<N>::f()      其中p的类型要依赖于模板参数T.

template <typename T>
class Shell {
public:template <int N>class In {public:template<int M>class Deep {public:virtual void f();};};
};template <typename T, int N>
class Weird
{
public:void case1(typename Shell<T>::template In<N>::template Deep<N>* p) {p->template Deep<N>::f();}void case2(typename Shell<T>::template In<N>::template Deep<N>& p) {p.template Deep<N>::f();}};

6.using-declaration中的依赖型名称 todo?

(p.s. 书上这部分的特性限制有一些貌似被修正了。todo)

template <typename T>
class BXT {
public:typedef T Mystery;template<typename U>struct Magic;
};template <typename T>
class DXTT :private BXT<T>
{
public:using typename BXT<T>::Mystery;//using BXT<T>::Mystery; 貌似现在这种写法可以通过编译Mystery* p;
};

(利用using引入名称类型 需要用typename显示指定,不过我本地不加typename编译也能通过)todo

template <typename T>
class DXTM :private BXT<T> {
public:using BXT<T>::template Magic;Magic<T>* plink;
};

(同样的书上说这种写法是非法的,但貌似现在标准规范修改了这个特性。)

7.ADL和显式模板实参

namespace N {class X{};template<int I> void select(X*);
}void g(N::X* xp)
{//using namespace N;select<3>(xp);
}

注:这种情况下不能使用ADL找到N空间下的select模板 ,因为分析的时候不知道select是一个模板所以就不知道<3>是一个模板实参列表。

八:派生和类模板

1.非依赖型基类

指  无需知道模板实参就可以完全确定类型的基类。

template <typename X>
class Base
{
public:int basefield;typedef int T;
};class D1 : public Base<Base<void> > {
public :void f() { basefield = 3; }
};template <typename T>
class D2 :public Base<double>
{
public:void f() { basefield = 7; }//正常访问继承成员T strange;//t是Base<double>::T 而不是模板参数T
};void g(D2<int*>& d2, int* p)
{d2.strange = p;//error 类型不匹配
}

注:对于模板中的非依赖型基类而言,如果在它的派生类中查找一个非受限名称,那么会先查找这个非依赖性基类,然后才查找模板参数列表。

2.依赖型基类

c++标准规定: 对于模板中的非依赖型名称,将在看到的第一时间进行查找。

template<typename T>
class DD :public Base<T> {
public:void f() { basefield = 0; }
};template<>
class Base<bool> {
public:enum {basefield = 42};
};void g(DD<bool>& d)
{d.f();
}

由于以上的规则,我们在第一次看到非依赖名称basefield时进行了 查找,确定为int型 之后的显示特化改变了basefield的类型 所以调用g时会产生错误。

//todo

C Templates学习笔记⑧:模板中的名称相关推荐

  1. 设计模式学习笔记——模板(Template)模式

    设计模式学习笔记--模板(Template)模式 @(设计模式)[设计模式, 模板模式, template, 模板方法] 设计模式学习笔记模板Template模式 基本介绍 模板案例 类图 实现代码 ...

  2. r语言c函数怎么用,R语言学习笔记——C#中如何使用R语言setwd()函数

    在R语言编译器中,设置当前工作文件夹可以用setwd()函数. > setwd("e://桌面//") > setwd("e:\桌面\") > ...

  3. 20190328学习笔记 - JSP 中的 tag 文件

    20190328学习笔记 - JSP 中的 tag 文件 对于tag 文件 1. 引入 tag 文件 2. 在/WEB-INF/tags/sys 下,新增一个gridselect.tag文件 3. 在 ...

  4. 图论01.最短路专题_学习笔记+模板

    图论01.最短路专题_学习笔记+模板 一.定义与性质 ● 需要的前导知识点 路径 最短路 有向图中的最短路.无向图中的最短路 单源最短路.每对结点之间的最短路 ● 最短路的性质 对于边权为正的图,任意 ...

  5. C++学习笔记:模板

    C++学习笔记:模板 1.函数模板 2.类模板 2.1类模板注意事项 2.2类模板中函数的创建时机 2.3类模板对象作函数参数时 2.4类模板与继承 2.5类模板分文件编写 2.6类模板友元 2.6. ...

  6. c#学习笔记05-treeview中添加图标

    创建树目录前面在学习笔记03中已经提到过 即树目录数据从XML文档中获取 添加图标主要用到ImageList控件 1.ImageList控件 在树目录对应存在的窗体中添加此控件 添加图标: 2.tre ...

  7. image是否有disabled属性_Vue学习笔记 模板语法、计算属性

    点击上方"蓝字"关注我们吧! vue学习笔记 官网:https://cn.vuejs.org/v2/guide/ 1.vue体验 demo示例: image.png 示例代码: & ...

  8. C++模板学习笔记——模板实参

    对于函数模板,编译器通过隐式推断模板实参.其中,从函数实参来确定模板实参的过程被称为模板实参推断.在模板实参推断过程中,编译器使用函数调用中的实参类型来寻找模板实参,用这些模板实参生成的函数版本与给定 ...

  9. C++学习笔记—模板与STL

    C++提高编程 本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用 1 模板 1.1 模板的概念 模板就是建立通用的模具,大大提高复用性 例如生活中的模板 一寸照片模板 PPT ...

最新文章

  1. 挖掘 OSINT 金矿——实习生和社交媒体
  2. 商汤科技 中科院自动化所:视觉跟踪之端到端的光流相关滤波 | CVPR 2018
  3. 【数据结构与算法】之有序数组中的单一元素的算法
  4. SAP Spartacus AutoFocus directive的一个例子
  5. 【强连通分量+概率】Bzoj2438 杀人游戏
  6. Jquery——hover与toggle
  7. Controller和RequestMapping
  8. Impala操作审计
  9. 台大李宏毅Machine Learning 2017Fall学习笔记 (13)Semi-supervised Learning
  10. 成功演示六要素之四五——可信与情感
  11. 内存一致性模型(Memory Consistency Models)
  12. 即时战略类游戏:北加尔Northgard for Mac中文版
  13. 最新的windows xp sp3序列号(绝对可通过正版验证)
  14. Hex转Bin小工具
  15. [转]PT与PX区别
  16. JP1081B/9700_USB网卡驱动
  17. 百度SiteApp构建网站APP
  18. 在centos7.7安装搜狗输入法踩坑日记
  19. adguard没有核心 core no_树莓派安装AdGuard Home屏蔽广告
  20. 【ASP.net】浏览器和服务器的交互

热门文章

  1. 《算法零基础》第9讲:算术基本定理
  2. FIDO U2F Message协议介绍
  3. android 白噪音闹钟,潮汐(睡眠白噪音番茄钟)
  4. 腾讯云cos本地和云端同步python工具类
  5. 视频压缩编码及视频文件格式
  6. 亚马逊(AWS) 创建EC2 - Windows
  7. ⅰsee是什么意思_I see 什么意思
  8. 浅谈vue项目上线问题
  9. 海说软件官网重装上线 同时发布两大视频处理技术
  10. 供应商管理及评审制度