C++ Template 模版中的名称(笔记)

1、名称查找

受限名称的名称查找在作用域内部进行,不考虑它的外围作用于(但是如果作用域是类,查找范围可以是它的基类)。

非受限名称可以由内至外在所有外围类中查找。先查找该类和基类,然后查找外围类的作用域,也成为普通查找(含有ADL)。


ADL(argument-dependent lookup)依赖于参数的查找,如果名称后面的括号里有一个或多个实参表达式,那么将查找这些实参的associated class(关联类)和assoicated namespace(关联名字空间)有以下规则:

(1)对于基本类型,该集合为空。

(2)对于指针和数组,该集合是所引用类型的associated class和assoicated namespace

(3)对于枚举,assoicated namespace是枚举声明所在的namespace。对于类成员,associated class指它所在的类

(4)对于class类型,associated class包括本身、外围类型、直接基类、间接基类。assoicated namespace是class所在的namespace。如果这个类是一个类模版实例化体,还包含:模版类型参数本身的类型、声明模版的模版实参所在的class和namespace。

(5)对于函数类型,包括所有参数和返回类型的assoicated namespace和associated class。


2、名称插入

友元名称插入

参考书中例子

template<typename T>
class C
{

	friend void f();
	friend void f(C<T> const&);

};

void g(C<int> *p)
{
	f();<span style="white-space:pre">	</span>/*此处不可见*/
	f(*p);<span style="white-space:pre">	</span><span style="font-family: Arial, Helvetica, sans-serif;">/*此处可见*/</span>

}
在类中的友元函数首次声明,通常而言,友元的声明在外不可见。但是,友元函数所在类属于ADL的关联类集合,可以通过参数找到。


插入式类名称

在类本身作用域中插入该类名称。

还是书中的例子

int C;

class C
{
private:
	int i[2];
public:
	static int f(){
		return sizeof(C);
	}
};

int f()
{
	return sizeof(C);
}

int main()
{
	std::cout << "C::f() = " << C::f() << ","<span style="white-space:pre">	</span>//返回类型C
		<< "::f() = " << ::f() << std::endl;<span style="white-space:pre">	</span>//返回变量C
}

3、解析模版

依赖型类型名称

比如Trap<T>::x *y

在某些时候会被解析为x*y,需要加关键字typename

规则:

(1)名称出现在一个模版中

(2)名称是受限的

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

(4)名称依赖于模版

例子在P127


依赖型模版名称

如果限定符号前面的名称的类型要依赖于某个函数模版,并且紧接在限定符后面的是一个template-id,那么就需要用关键字template

template<typename T>
class Shell
{
	public:
		template<int N>
		class In
		{
			public:
				template<int M>
				class Deep
				{
					virtual void f();
				};
		};
};
//当p是Shell的一个对象的时候,表达式为
p.template Deep<N>::f()

3、派生和类模版

非依赖型基类

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

例子P131.


依赖型基类

能有this->前缀的地方用前缀

在派生类中添加using-declaration

详细P133




学习的书籍为《C++ Templates 中文版》(人民邮电出版社)

所有原文和书上范例都来自于此






你可能感兴趣的:(C++ Template 模版中的名称(笔记))